/// <summary>
        /// Sends DHCP reply
        /// </summary>
        /// <param name="msgType">Type of DHCP message to send</param>
        /// <param name="ip">IP for client</param>
        /// <param name="replyData">Reply options (will be sent if requested)</param>
        /// <param name="otherForceOptions">Force reply options (will be sent anyway)</param>
        public void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData, Dictionary <DHCPOption, byte[]> otherForceOptions)
        {
            var replyBuffer = requestData;

            replyBuffer.op      = 2;                                                         // Reply
            replyBuffer.yiaddr  = ip.GetAddressBytes();                                      // Client's IP
            replyBuffer.options = CreateOptionStruct(msgType, replyData, otherForceOptions); // Options
            if (!string.IsNullOrEmpty(dhcpServer.ServerName))
            {
                var serverNameBytes = Encoding.ASCII.GetBytes(dhcpServer.ServerName);
                int len             = (serverNameBytes.Length > 63) ? 63 : serverNameBytes.Length;
                Array.Copy(serverNameBytes, replyBuffer.sname, len);
                replyBuffer.sname[len] = 0;
            }
            lock (requestSocket)
            {
                IPEndPoint endPoint;
                if ((replyBuffer.giaddr[0] == 0) && (replyBuffer.giaddr[1] == 0) &&
                    (replyBuffer.giaddr[2] == 0) && (replyBuffer.giaddr[3] == 0))
                {
                    requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
                    endPoint = new IPEndPoint(IPAddress.Broadcast, PORT_TO_SEND_TO_CLIENT);
                }
                else
                {
                    requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false);
                    endPoint = new IPEndPoint(new IPAddress(replyBuffer.giaddr), PORT_TO_SEND_TO_RELAY);
                }
                var DataToSend = BuildDataStructure(replyBuffer);
                requestSocket.SendTo(DataToSend, endPoint);
            }
        }
예제 #2
0
        private byte[] CreateOptionStruct(DHCPMsgType msgType, DHCPReplyOptions replyOptions)
        {
            byte[] resultOptions = null;

            // Option82?
            var relayInfo = OptionData.GetOptionData(DHCPOption.RelayInfo, _dhcpRequest.requestData);

            CreateOptionElement(ref resultOptions, DHCPOption.DHCPMessageTYPE, new [] { (byte)msgType });
            // Server identifier - our IP address
            if (_dhcpRequest.dhcpServer.ServerIdentifier != null)
            {
                CreateOptionElement(ref resultOptions, DHCPOption.ServerIdentifier, _dhcpRequest.dhcpServer.ServerIdentifier.GetAddressBytes());
            }

            // Requested options
            if (replyOptions != null)
            {
                foreach (var option in replyOptions.OtherOptions.Keys)
                {
                    CreateOptionElement(ref resultOptions, option, replyOptions.OtherOptions[option]);
                }
            }

            // Option 82? Send it back!
            if (relayInfo != null)
            {
                CreateOptionElement(ref resultOptions, DHCPOption.RelayInfo, relayInfo);
            }

            // Create the end option
            Array.Resize(ref resultOptions, resultOptions.Length + 1);
            Array.Copy(new byte[] { 255 }, 0, resultOptions, resultOptions.Length - 1, 1);
            return(resultOptions);
        }
예제 #3
0
        /// <summary>
        /// Sends DHCP reply
        /// </summary>
        /// <param name="msgType">Type of DHCP message to send</param>
        /// <param name="replyData">Reply options (will be sent if requested)</param>
        /// <param name="replyPort">Port to send on</param>
        public void Send(DHCPMsgType msgType, DHCPReplyOptions replyData, int replyPort)
        {
            var replyBuffer = _dhcpRequest.requestData;

            replyBuffer.op      = 2;                                      // Reply
            replyBuffer.options = CreateOptionStruct(msgType, replyData); // Options
            if (!string.IsNullOrEmpty(_dhcpRequest.dhcpServer.ServerName))
            {
                var serverNameBytes = Encoding.ASCII.GetBytes(_dhcpRequest.dhcpServer.ServerName);
                int len             = (serverNameBytes.Length > 63) ? 63 : serverNameBytes.Length;
                Array.Copy(serverNameBytes, replyBuffer.sname, len);
                replyBuffer.sname[len] = 0;
            }
            if (replyData.NextServer != null)
            {
                var nextServerBytes = replyData.NextServer.GetAddressBytes();
                Array.Copy(nextServerBytes, replyBuffer.siaddr, 4);
            }
            if (replyData.BootFileName != null)
            {
                var bootFileNameBytes = Encoding.ASCII.GetBytes(replyData.BootFileName);
                int len = (bootFileNameBytes.Length > 127) ? 127 : bootFileNameBytes.Length;
                Array.Copy(bootFileNameBytes, replyBuffer.file, len);
                replyBuffer.file[len] = 0;
            }
            lock (_dhcpRequest.requestSocket)
            {
                IPEndPoint endPoint;

                if (msgType == DHCPMsgType.DHCPACK)
                {
                    //Trace.WriteLine("Sending Acknowledgement to " + new IPAddress(replyBuffer.ciaddr) + ":" + replyPort);
                    _dhcpRequest.requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false);
                    endPoint = new IPEndPoint(new IPAddress(replyBuffer.ciaddr), replyPort);
                }
                else
                {
                    if ((replyBuffer.giaddr[0] == 0) && (replyBuffer.giaddr[1] == 0) &&
                        (replyBuffer.giaddr[2] == 0) && (replyBuffer.giaddr[3] == 0))
                    {
                        //Trace.WriteLine("Sending Offer To " + IPAddress.Broadcast + ":" + PORT_TO_SEND_TO_CLIENT);
                        _dhcpRequest.requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
                        endPoint = new IPEndPoint(IPAddress.Broadcast, PORT_TO_SEND_TO_CLIENT);
                    }
                    else
                    {
                        //Trace.WriteLine("Sending Offer To " + new IPAddress(replyBuffer.giaddr) + ":" + PORT_TO_SEND_TO_RELAY);
                        _dhcpRequest.requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false);
                        endPoint = new IPEndPoint(new IPAddress(replyBuffer.giaddr), PORT_TO_SEND_TO_RELAY);
                    }
                }
                var DataToSend = BuildDataStructure(replyBuffer);
                _dhcpRequest.requestSocket.SendTo(DataToSend, endPoint);
            }
        }
예제 #4
0
        /// <summary>
        /// Sends DHCP reply
        /// </summary>
        /// <param name="msgType">Type of DHCP message to send</param>
        /// <param name="ip">IP for client</param>
        /// <param name="replyData">Reply options (will be sent if requested)</param>
        /// <param name="otherForceOptions">Force reply options (will be sent anyway)</param>
        private void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData, Dictionary <DHCPOption, byte[]> otherForceOptions, IEnumerable <DHCPOption> forceOptions)
        {
            var replyBuffer = requestData;

            replyBuffer.op = 2; // Reply
            if (msgType == DHCPMsgType.DHCPOFFER || msgType == DHCPMsgType.DHCPACK)
            {
                replyBuffer.yiaddr = ip.GetAddressBytes(); // Client's IP
                if (replyData.ServerIpAddress != null)
                {
                    replyBuffer.siaddr = replyData.ServerIpAddress.GetAddressBytes();
                }
            }
            //IPAddress localIp = ((IPEndPoint)udp.Client.LocalEndPoint).Address;
            //replyData.ServerIdentifier = localIp;
            replyBuffer.options = CreateOptionStruct(msgType, replyData, otherForceOptions, forceOptions); // Options
            if (!string.IsNullOrEmpty(dhcpServer.ServerName))
            {
                var serverNameBytes = Encoding.ASCII.GetBytes(dhcpServer.ServerName);
                int len             = (serverNameBytes.Length > 63) ? 63 : serverNameBytes.Length;
                Array.Copy(serverNameBytes, replyBuffer.sname, len);
                replyBuffer.sname[len] = 0;
            }

            //lock (requestSocket)
            lock (udp)
            {
                var DataToSend = BuildDataStructure(replyBuffer);
                if (DataToSend.Length < 300)
                {
                    var sendArray = new byte[300];
                    Array.Copy(DataToSend, 0, sendArray, 0, DataToSend.Length);
                    DataToSend = sendArray;
                }

                if (dhcpServer.SendDhcpAnswerNetworkInterface != null)
                {
                    udp.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, (int)IPAddress.HostToNetworkOrder(dhcpServer.SendDhcpAnswerNetworkInterface.GetIPProperties().GetIPv4Properties().Index));
                }
                IPEndPoint endPoint = null;
                if ((replyBuffer.giaddr[0] == 0) && (replyBuffer.giaddr[1] == 0) &&
                    (replyBuffer.giaddr[2] == 0) && (replyBuffer.giaddr[3] == 0))
                {
                    endPoint            = new IPEndPoint(dhcpServer.BroadcastAddress, PORT_TO_SEND_TO_CLIENT);
                    udp.EnableBroadcast = true;
                    udp.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                }
                else
                {
                    endPoint = new IPEndPoint(new IPAddress(replyBuffer.giaddr), PORT_TO_SEND_TO_RELAY);
                    udp.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false);
                }
                udp.Send(DataToSend, DataToSend.Length, endPoint);
            }
        }
예제 #5
0
        static void discoverHandler(DHCPRequest dhcpRequest)
        {
            DHCPMsgType      type    = dhcpRequest.GetMsgType();
            String           mac     = Util.bytesToMac(dhcpRequest.GetChaddr());
            IPAddress        ip      = pool.offerIP(mac, dhcpRequest.GetRequestedIP());
            DHCPReplyOptions options = defaultOptions.clone();

            options.ServerIdentifier = localAddress;
            dhcpRequest.SendDHCPReply(DHCPMsgType.DHCPOFFER, ip, defaultOptions);
            sendNotify(DhcpNotify.NotifyType.DISCOVER, String.Format("RTDhcpServer receives DHCP discover message from {0}, offer {1}", mac, ip));
        }
        /// <summary>
        /// Sends DHCP reply
        /// </summary>
        /// <param name="msgType">Type of DHCP message to send</param>
        /// <param name="ip">IP for client</param>
        /// <param name="replyData">Reply options (will be sent if requested)</param>
        /// <param name="otherForceOptions">Force reply options (will be sent anyway)</param>
        private void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData, Dictionary <DHCPOption, byte[]> otherForceOptions, IEnumerable <DHCPOption> forceOptions)
        {
            var replyBuffer = requestData;

            replyBuffer.op     = 2;                    // Reply
            replyBuffer.yiaddr = ip.GetAddressBytes(); // Client's IP
            if (replyData.ServerIpAddress != null)
            {
                replyBuffer.siaddr = replyData.ServerIpAddress.GetAddressBytes();
            }
            replyBuffer.options = CreateOptionStruct(msgType, replyData, otherForceOptions, forceOptions); // Options
            if (!string.IsNullOrEmpty(dhcpServer.ServerName))
            {
                var serverNameBytes = Encoding.ASCII.GetBytes(dhcpServer.ServerName);
                int len             = (serverNameBytes.Length > 63) ? 63 : serverNameBytes.Length;
                Array.Copy(serverNameBytes, replyBuffer.sname, len);
                replyBuffer.sname[len] = 0;
            }
            lock (requestSocket)
            {
                var DataToSend = BuildDataStructure(replyBuffer);
                if (DataToSend.Length < 300)
                {
                    var sendArray = new byte[300];
                    Array.Copy(DataToSend, 0, sendArray, 0, DataToSend.Length);
                    DataToSend = sendArray;
                }

                IPEndPoint endPoint;
                if ((replyBuffer.giaddr[0] == 0) && (replyBuffer.giaddr[1] == 0) &&
                    (replyBuffer.giaddr[2] == 0) && (replyBuffer.giaddr[3] == 0))
                {
                    //requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
                    //endPoint = new IPEndPoint(dhcpServer.BroadcastAddress, PORT_TO_SEND_TO_CLIENT);

                    var udp = new UdpClient();
                    udp.EnableBroadcast = true;
                    udp.Send(DataToSend, DataToSend.Length, new IPEndPoint(dhcpServer.BroadcastAddress, 68));
                    udp.Close();
                }
                else
                {
                    requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false);
                    endPoint = new IPEndPoint(new IPAddress(replyBuffer.giaddr), PORT_TO_SEND_TO_RELAY);
                    requestSocket.SendTo(DataToSend, endPoint);
                }
            }
        }
예제 #7
0
파일: DHCP.cs 프로젝트: LipkeGu/bootpd
        public DHCPClient(Guid guid, string mac, SocketType type, IPEndPoint endpoint)
        {
            this.type = type;
            this.endp = endpoint;
            this.wdsclient = false;
            this.pollInterval = Convert.ToInt16(Settings.PollInterval);
            this.retrycount = Convert.ToInt16(Settings.RetryCount);

            this.actionDone = false;
            this.guid = guid;
            this.mac = mac;
            this.id = string.Format("{0}-{1}", this.guid, this.mac);
            this.adminMessage = "Client ID: {0}".F(this.id);
            this.nextAction = NextActionOptionValues.Approval;
            this.msgType = DHCPMsgType.Offer;
            this.arch = Architecture.Intelx86PC;
            this.bootfile = string.Empty;

            this.undi_major = 2;
            this.undi_minor = 1;
        }
예제 #8
0
파일: cDHCP.cs 프로젝트: emacslisp/cs
        //mac announced itself, established IP etc....
        //send the offer to the mac
        public void SendDHCPMessage(DHCPMsgType msgType, cDHCPStruct ddHcpS)
        {
            byte[] Subn, HostID, DataToSend;


            //we shall leave everything as is structure wise
            //shall CHANGE the type to OFFER
            //shall set the client's IP-Address
            try
            {
                //change message type to reply
                ddHcpS.dStruct.D_op = 2; //reply
                //subnet
                Subn = IPAddress.Parse(ddHcpS.dData.SubMask).GetAddressBytes();
                //create your ip address
                ddHcpS.dStruct.D_yiaddr = IPAddress.Parse(ddHcpS.dData.IPAddr).GetAddressBytes();

                //Host ID
                HostID = System.Text.Encoding.ASCII.GetBytes(ddHcpS.dData.ServerName);

                CreateOptionStruct(ref ddHcpS, msgType);
                //send the data to the unit
                DataToSend = BuildDataStructure(ddHcpS.dStruct);
                cUdp.SendData(DataToSend);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                Subn = null;
                //LeaseTime= null;
                HostID = null;

                DataToSend = null;
            }
        }
예제 #9
0
파일: cDHCP.cs 프로젝트: emacslisp/cs
        private void CreateOptionStruct(ref cDHCPStruct ddHcps, DHCPMsgType OptionReplyMsg)
        {
            byte[] PReqList, t1, LeaseTime, MyIp;

            try
            {
                //we look for the parameter request list
                PReqList = GetOptionData(DHCPOptionEnum.ParameterRequestList, ddHcps);
                //erase the options array, and set the message type to ack
                ddHcps.dStruct.D_options = null;
                CreateOptionElement(DHCPOptionEnum.DHCPMessageTYPE, new byte[] { (byte)OptionReplyMsg }, ref ddHcps.dStruct.D_options);
                //server identifier, my IP
                MyIp = IPAddress.Parse(ddHcps.dData.MyIP).GetAddressBytes();
                CreateOptionElement(DHCPOptionEnum.ServerIdentifier, MyIp, ref ddHcps.dStruct.D_options);


                //PReqList contains the option data in a byte that is requested by the unit
                foreach (byte i in PReqList)
                {
                    t1 = null;
                    switch ((DHCPOptionEnum)i)
                    {
                    case DHCPOptionEnum.SubnetMask:
                        t1 = IPAddress.Parse(ddHcps.dData.SubMask).GetAddressBytes();
                        break;

                    case DHCPOptionEnum.Router:
                        t1 = IPAddress.Parse(ddHcps.dData.RouterIP).GetAddressBytes();
                        break;

                    case DHCPOptionEnum.DomainNameServer:
                        t1 = IPAddress.Parse(ddHcps.dData.DomainIP).GetAddressBytes();
                        break;

                    case DHCPOptionEnum.DomainName:
                        t1 = System.Text.Encoding.ASCII.GetBytes(ddHcps.dData.ServerName);
                        break;

                    case DHCPOptionEnum.ServerIdentifier:
                        t1 = IPAddress.Parse(ddHcps.dData.MyIP).GetAddressBytes();
                        break;

                    case DHCPOptionEnum.LogServer:
                        t1 = System.Text.Encoding.ASCII.GetBytes(ddHcps.dData.LogServerIP);
                        break;

                    case DHCPOptionEnum.NetBIOSoverTCPIPNameServer:
                        break;
                    }
                    if (t1 != null)
                    {
                        CreateOptionElement((DHCPOptionEnum)i, t1, ref ddHcps.dStruct.D_options);
                    }
                }

                //lease time
                LeaseTime    = new byte[4];
                LeaseTime[3] = (byte)(ddHcps.dData.LeaseTime);
                LeaseTime[2] = (byte)(ddHcps.dData.LeaseTime >> 8);
                LeaseTime[1] = (byte)(ddHcps.dData.LeaseTime >> 16);
                LeaseTime[0] = (byte)(ddHcps.dData.LeaseTime >> 24);
                CreateOptionElement(DHCPOptionEnum.IPAddressLeaseTime, LeaseTime, ref ddHcps.dStruct.D_options);
                CreateOptionElement(DHCPOptionEnum.RenewalTimeValue_T1, LeaseTime, ref ddHcps.dStruct.D_options);
                CreateOptionElement(DHCPOptionEnum.RebindingTimeValue_T2, LeaseTime, ref ddHcps.dStruct.D_options);
                //create the end option
                Array.Resize(ref ddHcps.dStruct.D_options, ddHcps.dStruct.D_options.Length + 1);
                Array.Copy(new byte[] { 255 }, 0, ddHcps.dStruct.D_options, ddHcps.dStruct.D_options.Length - 1, 1);
                //send the data to the unit
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                LeaseTime = null;
                PReqList  = null;
                t1        = null;
            }
        }
        private byte[] CreateOptionStruct(DHCPMsgType msgType, DHCPReplyOptions replyOptions, Dictionary<DHCPOption, byte[]> otherForceOptions)
        {
            byte[] resultOptions = null;
            // Requested options
            var reqList = GetRequestedOptionsList();
            // Option82?
            var relayInfo = this.GetOptionData(DHCPOption.RelayInfo);
            CreateOptionElement(ref resultOptions, DHCPOption.DHCPMessageTYPE, new byte[] { (byte)msgType });
            // Server identifier - our IP address
            if ((replyOptions != null) && (replyOptions.ServerIdentifier != null))
                CreateOptionElement(ref resultOptions, DHCPOption.ServerIdentifier, replyOptions.ServerIdentifier.GetAddressBytes());

            // Requested options
            if ((reqList != null) && (replyOptions != null))
                foreach (DHCPOption i in reqList)
                {
                    byte[] optionData = null;
                    // If it's force option - ignore it. We'll send it later.
                    if ((otherForceOptions != null) && (otherForceOptions.TryGetValue(i, out optionData)))
                        continue;
                    switch (i)
                    {
                        case DHCPOption.SubnetMask:
                            if (replyOptions.SubnetMask != null)
                                optionData = replyOptions.SubnetMask.GetAddressBytes();
                            break;
                        case DHCPOption.Router:
                            if (replyOptions.RouterIP != null)
                                optionData = replyOptions.RouterIP.GetAddressBytes();
                            break;
                        case DHCPOption.DomainNameServers:
                            if (replyOptions.DomainNameServers != null)
                            {
                                optionData = new byte[] { };
                                foreach (var dns in replyOptions.DomainNameServers)
                                {
                                    var dnsserv = dns.GetAddressBytes();
                                    Array.Resize(ref optionData, optionData.Length + 4);
                                    Array.Copy(dnsserv, 0, optionData, optionData.Length - 4, 4);
                                }
                            }
                            break;
                        case DHCPOption.DomainName:
                            if (!string.IsNullOrEmpty(replyOptions.DomainName))
                                optionData = System.Text.Encoding.ASCII.GetBytes(replyOptions.DomainName);
                            break;
                        case DHCPOption.ServerIdentifier:
                            if (replyOptions.ServerIdentifier != null)
                                optionData = replyOptions.ServerIdentifier.GetAddressBytes();
                            break;
                        case DHCPOption.LogServer:
                            if (replyOptions.LogServerIP != null)
                                optionData = replyOptions.LogServerIP.GetAddressBytes();
                            break;
                        case DHCPOption.StaticRoutes:
                        case DHCPOption.StaticRoutesWin:
                            if (replyOptions.StaticRoutes != null)
                            {
                                optionData = new byte[] { };
                                foreach (var route in replyOptions.StaticRoutes)
                                {
                                    var routeData = route.BuildRouteData();
                                    Array.Resize(ref optionData, optionData.Length + routeData.Length);
                                    Array.Copy(routeData, 0, optionData, optionData.Length - routeData.Length, routeData.Length);
                                }
                            }
                            break;
                        default:
                            replyOptions.OtherRequestedOptions.TryGetValue(i, out optionData);
                            break;
                    }
                    if (optionData != null)
                        CreateOptionElement(ref resultOptions, i, optionData);
                }

            if (GetMsgType() != DHCPMsgType.DHCPINFORM)
            {
                // Lease time
                if (replyOptions != null)
                {
                    var leaseTime = new byte[4];
                    leaseTime[3] = (byte)(replyOptions.IPAddressLeaseTime);
                    leaseTime[2] = (byte)(replyOptions.IPAddressLeaseTime >> 8);
                    leaseTime[1] = (byte)(replyOptions.IPAddressLeaseTime >> 16);
                    leaseTime[0] = (byte)(replyOptions.IPAddressLeaseTime >> 24);
                    CreateOptionElement(ref resultOptions, DHCPOption.IPAddressLeaseTime, leaseTime);
                    leaseTime[3] = (byte)(replyOptions.RenewalTimeValue_T1);
                    leaseTime[2] = (byte)(replyOptions.RenewalTimeValue_T1 >> 8);
                    leaseTime[1] = (byte)(replyOptions.RenewalTimeValue_T1 >> 16);
                    leaseTime[0] = (byte)(replyOptions.RenewalTimeValue_T1 >> 24);
                    CreateOptionElement(ref resultOptions, DHCPOption.RenewalTimeValue_T1, leaseTime);
                    leaseTime[3] = (byte)(replyOptions.RebindingTimeValue_T2);
                    leaseTime[2] = (byte)(replyOptions.RebindingTimeValue_T2 >> 8);
                    leaseTime[1] = (byte)(replyOptions.RebindingTimeValue_T2 >> 16);
                    leaseTime[0] = (byte)(replyOptions.RebindingTimeValue_T2 >> 24);
                    CreateOptionElement(ref resultOptions, DHCPOption.RebindingTimeValue_T2, leaseTime);
                }
            }
            // Other requested options
            if (otherForceOptions != null)
                foreach (var option in otherForceOptions.Keys)
                {
                    CreateOptionElement(ref resultOptions, option, otherForceOptions[option]);
                    if (option == DHCPOption.RelayInfo) relayInfo = null;
                }

            // Option 82? Send it back!
            if (relayInfo != null)
                CreateOptionElement(ref resultOptions, DHCPOption.RelayInfo, relayInfo);

            // Create the end option
            Array.Resize(ref resultOptions, resultOptions.Length + 1);
            Array.Copy(new byte[] { 255 }, 0, resultOptions, resultOptions.Length - 1, 1);
            return resultOptions;
        }
 /// <summary>
 /// Sends DHCP reply
 /// </summary>
 /// <param name="msgType">Type of DHCP message to send</param>
 /// <param name="ip">IP for client</param>
 /// <param name="replyData">Reply options (will be sent if requested)</param>
 public void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData)
 {
     SendDHCPReply(msgType, ip, replyData, null);
 }
 /// <summary>
 /// Sends DHCP reply
 /// </summary>
 /// <param name="msgType">Type of DHCP message to send</param>
 /// <param name="ip">IP for client</param>
 /// <param name="replyData">Reply options (will be sent if requested)</param>
 /// <param name="forceOptions">Force reply options (will be sent anyway)</param>
 public void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData,
                           IEnumerable <DHCPOption> forceOptions)
 {
     SendDHCPReply(msgType, ip, replyData, null, forceOptions);
 }
 /// <summary>
 /// Sends DHCP reply
 /// </summary>
 /// <param name="msgType">Type of DHCP message to send</param>
 /// <param name="ip">IP for client</param>
 /// <param name="replyData">Reply options (will be sent if requested)</param>
 /// <param name="otherForceOptions">Force reply options (will be sent anyway)</param>
 public void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData,
                           Dictionary <DHCPOption, byte[]> otherForceOptions)
 {
     SendDHCPReply(msgType, ip, replyData, otherForceOptions, null);
 }
 /// <summary>
 /// Sends DHCP reply
 /// </summary>
 /// <param name="msgType">Type of DHCP message to send</param>
 /// <param name="ip">IP for client</param>
 /// <param name="replyData">Reply options (will be sent if requested)</param>
 public void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData)
 {
     SendDHCPReply(msgType, ip, replyData, null, null);
 }
        private byte[] CreateOptionStruct(DHCPMsgType msgType, DHCPReplyOptions replyOptions, Dictionary <DHCPOption, byte[]> otherForceOptions, IEnumerable <DHCPOption> forceOptions)
        {
            Dictionary <DHCPOption, byte[]> options = new Dictionary <DHCPOption, byte[]>();

            byte[] resultOptions = null;
            // Requested options
            var reqList = GetRequestedOptionsList();
            // Option82?
            var relayInfo = this.GetOptionData(DHCPOption.RelayInfo);

            CreateOptionElement(ref resultOptions, DHCPOption.DHCPMessageTYPE, new byte[] { (byte)msgType });
            // Server identifier - our IP address
            if ((replyOptions != null) && (replyOptions.ServerIdentifier != null))
            {
                options[DHCPOption.ServerIdentifier] = replyOptions.ServerIdentifier.GetAddressBytes();
            }

            if (reqList == null && forceOptions != null)
            {
                reqList = new DHCPOption[0];
            }

            // Requested options
            if ((reqList != null) && (replyOptions != null))
            {
                foreach (DHCPOption i in reqList.Union(forceOptions).Distinct().OrderBy(x => (int)x))
                {
                    byte[] optionData = null;
                    // If it's force option - ignore it. We'll send it later.
                    if ((otherForceOptions != null) && (otherForceOptions.TryGetValue(i, out optionData)))
                    {
                        continue;
                    }
                    switch (i)
                    {
                    case DHCPOption.SubnetMask:
                        if (replyOptions.SubnetMask != null)
                        {
                            optionData = replyOptions.SubnetMask.GetAddressBytes();
                        }
                        break;

                    case DHCPOption.Router:
                        if (replyOptions.RouterIP != null)
                        {
                            optionData = replyOptions.RouterIP.GetAddressBytes();
                        }
                        break;

                    case DHCPOption.DomainNameServers:
                        if (replyOptions.DomainNameServers != null)
                        {
                            optionData = new byte[] { };
                            foreach (var dns in replyOptions.DomainNameServers)
                            {
                                var dnsserv = dns.GetAddressBytes();
                                Array.Resize(ref optionData, optionData.Length + 4);
                                Array.Copy(dnsserv, 0, optionData, optionData.Length - 4, 4);
                            }
                        }
                        break;

                    case DHCPOption.DomainName:
                        if (!string.IsNullOrEmpty(replyOptions.DomainName))
                        {
                            optionData = System.Text.Encoding.ASCII.GetBytes(replyOptions.DomainName);
                        }
                        break;

                    case DHCPOption.ServerIdentifier:
                        if (replyOptions.ServerIdentifier != null)
                        {
                            optionData = replyOptions.ServerIdentifier.GetAddressBytes();
                        }
                        break;

                    case DHCPOption.LogServer:
                        if (replyOptions.LogServerIP != null)
                        {
                            optionData = replyOptions.LogServerIP.GetAddressBytes();
                        }
                        break;

                    case DHCPOption.StaticRoutes:
                    case DHCPOption.StaticRoutesWin:
                        if (replyOptions.StaticRoutes != null)
                        {
                            optionData = new byte[] { };
                            foreach (var route in replyOptions.StaticRoutes)
                            {
                                var routeData = route.BuildRouteData();
                                Array.Resize(ref optionData, optionData.Length + routeData.Length);
                                Array.Copy(routeData, 0, optionData, optionData.Length - routeData.Length, routeData.Length);
                            }
                        }
                        break;

                    default:
                        replyOptions.OtherRequestedOptions.TryGetValue(i, out optionData);
                        break;
                    }
                    if (optionData != null)
                    {
                        options[i] = optionData;
                    }
                }
            }

            if (GetMsgType() != DHCPMsgType.DHCPINFORM)
            {
                // Lease time
                if (replyOptions != null)
                {
                    var leaseTime = new byte[4];
                    leaseTime[3] = (byte)(replyOptions.IPAddressLeaseTime);
                    leaseTime[2] = (byte)(replyOptions.IPAddressLeaseTime >> 8);
                    leaseTime[1] = (byte)(replyOptions.IPAddressLeaseTime >> 16);
                    leaseTime[0] = (byte)(replyOptions.IPAddressLeaseTime >> 24);
                    options[DHCPOption.IPAddressLeaseTime] = leaseTime;
                    if (replyOptions.RenewalTimeValue_T1.HasValue)
                    {
                        leaseTime[3] = (byte)(replyOptions.RenewalTimeValue_T1);
                        leaseTime[2] = (byte)(replyOptions.RenewalTimeValue_T1 >> 8);
                        leaseTime[1] = (byte)(replyOptions.RenewalTimeValue_T1 >> 16);
                        leaseTime[0] = (byte)(replyOptions.RenewalTimeValue_T1 >> 24);
                        options[DHCPOption.RenewalTimeValue_T1] = leaseTime;
                    }
                    if (replyOptions.RebindingTimeValue_T2.HasValue)
                    {
                        leaseTime[3] = (byte)(replyOptions.RebindingTimeValue_T2);
                        leaseTime[2] = (byte)(replyOptions.RebindingTimeValue_T2 >> 8);
                        leaseTime[1] = (byte)(replyOptions.RebindingTimeValue_T2 >> 16);
                        leaseTime[0] = (byte)(replyOptions.RebindingTimeValue_T2 >> 24);
                        options[DHCPOption.RebindingTimeValue_T2] = leaseTime;
                    }
                }
            }
            // Other requested options
            if (otherForceOptions != null)
            {
                foreach (var option in otherForceOptions.Keys)
                {
                    options[option] = otherForceOptions[option];
                    if (option == DHCPOption.RelayInfo)
                    {
                        relayInfo = null;
                    }
                }
            }

            // Option 82? Send it back!
            if (relayInfo != null)
            {
                options[DHCPOption.RelayInfo] = relayInfo;
            }

            foreach (var option in options.OrderBy(x => (int)x.Key))
            {
                CreateOptionElement(ref resultOptions, option.Key, option.Value);
            }

            // Create the end option
            Array.Resize(ref resultOptions, resultOptions.Length + 1);
            Array.Copy(new byte[] { 255 }, 0, resultOptions, resultOptions.Length - 1, 1);
            return(resultOptions);
        }
 /// <summary>
 /// Sends DHCP reply
 /// </summary>
 /// <param name="msgType">Type of DHCP message to send</param>
 /// <param name="ip">IP for client</param>
 /// <param name="replyData">Reply options (will be sent if requested)</param>
 /// <param name="otherForceOptions">Force reply options (will be sent anyway)</param>
 public void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData, Dictionary<DHCPOption, byte[]> otherForceOptions)
 {
     var replyBuffer = requestData;
     replyBuffer.op = 2; // Reply
     replyBuffer.yiaddr = ip.GetAddressBytes(); // Client's IP
     replyBuffer.options = CreateOptionStruct(msgType, replyData, otherForceOptions); // Options
     if (!string.IsNullOrEmpty(dhcpServer.ServerName))
     {
         var serverNameBytes = Encoding.ASCII.GetBytes(dhcpServer.ServerName);
         int len = (serverNameBytes.Length > 63) ? 63 : serverNameBytes.Length;
         Array.Copy(serverNameBytes, replyBuffer.sname, len);
         replyBuffer.sname[len] = 0;
     }
     lock (requestSocket)
     {
         IPEndPoint endPoint;
         if ((replyBuffer.giaddr[0] == 0) && (replyBuffer.giaddr[1] == 0) &&
             (replyBuffer.giaddr[2] == 0) && (replyBuffer.giaddr[3] == 0))
         {
             requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
             endPoint = new IPEndPoint(IPAddress.Broadcast, PORT_TO_SEND_TO_CLIENT);
         }
         else
         {
             requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false);
             endPoint = new IPEndPoint(new IPAddress(replyBuffer.giaddr), PORT_TO_SEND_TO_RELAY);
         }
         var DataToSend = BuildDataStructure(replyBuffer);
         requestSocket.SendTo(DataToSend, endPoint);
     }
 }
        /// <summary>
        /// Sends DHCP reply
        /// </summary>
        /// <param name="msgType">Type of DHCP message to send</param>
        /// <param name="ip">IP for client</param>
        /// <param name="replyData">Reply options (will be sent if requested)</param>
        /// <param name="otherForceOptions">Force reply options (will be sent anyway)</param>
        private async void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData, Dictionary <DHCPOption, byte[]> otherForceOptions, IEnumerable <DHCPOption> forceOptions)
        {
            var replyBuffer = requestData;

            replyBuffer.op     = 2;                    // Reply
            replyBuffer.yiaddr = ip.GetAddressBytes(); // Client's IP
            if (replyData.ServerIpAddress != null)
            {
                replyBuffer.siaddr = replyData.ServerIpAddress.GetAddressBytes();
            }
            replyBuffer.options = CreateOptionStruct(msgType, replyData, otherForceOptions, forceOptions); // Options
            if (!string.IsNullOrEmpty(dhcpServer.ServerName))
            {
                var serverNameBytes = Encoding.ASCII.GetBytes(dhcpServer.ServerName);
                int len             = (serverNameBytes.Length > 63) ? 63 : serverNameBytes.Length;
                Array.Copy(serverNameBytes, replyBuffer.sname, len);
                replyBuffer.sname[len] = 0;
            }
            //lock (requestSocket)
            {
                var DataToSend = BuildDataStructure(replyBuffer);
                if (DataToSend.Length < 300)
                {
                    var sendArray = new byte[300];
                    Array.Copy(DataToSend, 0, sendArray, 0, DataToSend.Length);
                    DataToSend = sendArray;
                }

                if ((replyBuffer.giaddr[0] == 0) && (replyBuffer.giaddr[1] == 0) &&
                    (replyBuffer.giaddr[2] == 0) && (replyBuffer.giaddr[3] == 0))
                {
                    //requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
                    //endPoint = new IPEndPoint(dhcpServer.BroadcastAddress, PORT_TO_SEND_TO_CLIENT);

                    //var udp = new UdpClient();
                    //udp.EnableBroadcast = true;
                    //udp.Send(DataToSend, DataToSend.Length, new IPEndPoint(dhcpServer.BroadcastAddress, 68));
                    //udp.Close();

                    var datagramsocket = new Windows.Networking.Sockets.DatagramSocket();

                    using (var stream = await datagramsocket.GetOutputStreamAsync(new Windows.Networking.HostName(dhcpServer.BroadcastAddress), PORT_TO_SEND_TO_CLIENT.ToString()))
                    {
                        using (var datawriter = new Windows.Storage.Streams.DataWriter(stream))
                        {
                            datawriter.WriteBytes(DataToSend);
                            await datawriter.StoreAsync();
                        }
                    }
                }
                else
                {
                    //requestSocket .SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false);
                    //endPoint = new IPEndPoint(new IPAddress(replyBuffer.giaddr), PORT_TO_SEND_TO_RELAY);
                    //requestSocket.SendTo(DataToSend, endPoint);

                    using (var stream = await requestSocket.GetOutputStreamAsync(new Windows.Networking.HostName(new IPAddress(replyBuffer.giaddr).ToString()), PORT_TO_SEND_TO_RELAY.ToString()))
                    {
                        using (var datawriter = new Windows.Storage.Streams.DataWriter(stream))
                        {
                            datawriter.WriteBytes(DataToSend);
                            await datawriter.StoreAsync();
                        }
                    }
                }
            }
        }