Beispiel #1
0
        private const ushort DELAY = 0x1388;    // 5 s

        public void Run(IPAddress iPAddress, string dns, string subnetMask, string serverIdentifier, string routerIP)
        {
            UpdateStatus($"IP address:\t{iPAddress}");
            UpdateStatus($"DNS:\t{dns}");
            UpdateStatus($"SUBMASK:\t{subnetMask}");
            UpdateStatus($"SERVER IDENTIFIER:\t{serverIdentifier}");
            UpdateStatus($"ROUTER IP:\t{routerIP}");

            var server = new Dhcp(iPAddress);

            UpdateStatus("SETTATO L'IP DEL SERVER");
            server.ServerName = dns;
            UpdateStatus("SETTATO IL DNS DEL SERVER");
            server.BroadcastAddress = IPAddress.Broadcast.ToString();
            UpdateStatus("SETTATO IN BROADCAST IL SERVER");
            server.OnDataReceived += (sender, dhcpRequest) =>
            {
                UpdateStatus("GENERATO NUOVO EVENTO NEL SERVER");
                try
                {
                    var type = dhcpRequest.GetMsgType();
                    UpdateStatus($"TIPO DI RICHIESTA RICEVUTA DAL SERVER:\t{type}");
                    var ip = iPAddress;

                    var replyOptions = new DhcpReplyOptions();
                    UpdateStatus("SETTAGGIO DELLA RISPOSTA DAL SERVER IN CORSO...");
                    replyOptions.SubnetMask = IPAddress.Parse(subnetMask);
                    UpdateStatus($"SUBNETMASK:\t{replyOptions.SubnetMask}");
                    replyOptions.DomainName = server.ServerName;
                    UpdateStatus($"DOMAIN NAME:\t{replyOptions.DomainName}");
                    replyOptions.ServerIdentifier = IPAddress.Parse(serverIdentifier);
                    UpdateStatus($"SERVER IDENTIFIER:\t{replyOptions.ServerIdentifier}");
                    replyOptions.RouterIP = IPAddress.Parse(routerIP);
                    UpdateStatus($"IP ROUTER:\t{replyOptions.RouterIP}");
                    replyOptions.DomainNameServers = new IPAddress[]
                    { IPAddress.Parse("8.8.8.8"), IPAddress.Parse("8.8.4.4") };
                    UpdateStatus("CONFIGURAZIONE DEL DOMINIO DEL SERVER");

                    if (type == DhcpMsgType.DHCPDISCOVER)
                    {
                        UpdateStatus($"RISPOSTA\t->\tTIPO MESSAGGIO:{DhcpMsgType.DHCPOFFER}");
                        UpdateStatus($"RISPOSTA\t->\tIP:{ip}");
                        dhcpRequest.SendDHCPReply(DhcpMsgType.DHCPOFFER, ip, replyOptions);
                    }
                    if (type == DhcpMsgType.DHCPREQUEST)
                    {
                        UpdateStatus($"RISPOSTA\t->\tTIPO MESSAGGIO:{DhcpMsgType.DHCPACK}");
                        UpdateStatus($"RISPOSTA\t->\tIP:{ip}");
                        dhcpRequest.SendDHCPReply(DhcpMsgType.DHCPACK, ip, replyOptions);
                    }
                }
                catch (Exception e)
                {
                    UpdateStatus($"EXCEPTION IN SERVER:\t{e.Message}");
                }
            };
            UpdateStatus("ESECUZIONE DEL SERVER DHCP IN CORSO...");
            server.Start();
        }
Beispiel #2
0
        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))
            {
                if (forceOptions == null)
                {
                    forceOptions = new List <DhcpOption>();
                }
            }

            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);
        }
Beispiel #3
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 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();
                        }
                    }
                }
            }
        }
Beispiel #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="forceOptions">Force reply options (will be sent anyway)</param>
 internal void SendDHCPReply(DhcpMsgType msgType, IPAddress ip, DhcpReplyOptions replyData,
                             IEnumerable <DhcpOption> forceOptions)
 {
     SendDHCPReply(msgType, ip, replyData, null, forceOptions);
 }
Beispiel #5
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>
 internal void SendDHCPReply(DhcpMsgType msgType, IPAddress ip, DhcpReplyOptions replyData,
                             Dictionary <DhcpOption, byte[]> otherForceOptions)
 {
     SendDHCPReply(msgType, ip, replyData, otherForceOptions, null);
 }
Beispiel #6
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>
 internal void SendDHCPReply(DhcpMsgType msgType, IPAddress ip, DhcpReplyOptions replyData)
 {
     SendDHCPReply(msgType, ip, replyData, null, null);
 }