/// <summary>
        /// Restarts a given OpenVPN client service (connection)
        /// </summary>
        /// <param name="instance"></param>
        /// <returns>Refreshed instance that matches the ClientInstance given</returns>
        public async Task <ClientInstance> RestartClientService(ClientInstance instance)
        {
            if (instance == null)
            {
                throw new ArgumentNullException(nameof(instance));
            }
            if (csrfMagicToken == null)
            {
                throw new InvalidOperationException("CSRF Token was not found/parsed, this is a bug");
            }
            if (clientInstances.Contains(instance))
            {
                var request = context.CreateHttpRequestMessage(HttpMethod.Post, "status_services.php");
                request.Content = new FormUrlEncodedContent(new Dictionary <string, string>
                {
                    { "__csrf_magic", csrfMagicToken },
                    { "ajax", "ajax" },
                    { "mode", "restartservice" },
                    { "service", "openvpn" },
                    { "vpnmode", "client" },
                    { "zone", "client" },
                    { "id", instance.ID }
                });
                await context.SendAsync(request); // no need to check response content (there's none)
                await Refresh();

                return(clientInstances.FirstOrDefault(c => c.ID == instance.ID));
            }
            else
            {
                throw new InvalidOperationException("Given instance is not part of known client connections, try refreshing list via call to GetStatusOpenVPN again");
            }
        }
        internal static async Task <string> GetStatusOpenVPNContentAsync(PfSenseContext context)
        {
            var request  = context.CreateHttpRequestMessage(HttpMethod.Get, "status_openvpn.php");
            var response = await context.SendAsync(request);

            return(await response.Content.ReadAsStringAsync());
        }
        public async Task SaveDefaultGateways(bool applyChanges = false)
        {
            var request = context.CreateHttpRequestMessage(HttpMethod.Post, "system_gateways.php");

            request.Content = new FormUrlEncodedContent(new Dictionary <string, string>
            {
                { "__csrf_magic", formSaveDefaultGatewaysCsrfToken },
                { "defaultgw4", DefaultGatewayIPv4.Selected.InternalName },
                { "defaultgw6", DefaultGatewayIPv6.Selected.InternalName },
                { "save", "Save" }
            });
            var response = await context.SendAsync(request);

            parsePageContent(await response.Content.ReadAsStringAsync());

            if (applyChanges)
            {
                await ApplyChanges();
            }
        }
        /// <summary>
        /// If interface is configured with DHCP, perform a DHCP Release
        /// </summary>
        /// <param name="relinquishLease">Send gratuitous DHCP release message to server</param>
        /// <remarks>https://github.com/pfsense/pfsense/commit/718432f1a12b828214413881d4b9d612c2ef3c09</remarks>
        public async Task DHCPRelease(Interface netInterface, bool relinquishLease = false)
        {
            if (netInterface == null)
            {
                throw new ArgumentNullException(nameof(netInterface));
            }
            if (interfaces.Contains(netInterface))
            {
                if (netInterface.DHCPStatus == DHCPStatuses.Up)
                {
                    if (
                        netInterface.dhcpReleaseFormCsrfToken != null &&
                        netInterface.dhcpReleaseFormIfDescr != null &&
                        netInterface.dhcpReleaseFormStatus != null &&
                        netInterface.dhcpReleaseFormIf != null &&
                        netInterface.dhcpReleaseFormIpV != null
                        )
                    {
                        var request    = context.CreateHttpRequestMessage(HttpMethod.Post, "status_interfaces.php");
                        var formParams = new Dictionary <string, string>()
                        {
                            { "__csrf_magic", netInterface.dhcpReleaseFormCsrfToken },
                            { "ifdescr", netInterface.dhcpReleaseFormIfDescr },
                            { "status", netInterface.dhcpReleaseFormStatus },
                            { "submit", "Release" },
                            { "relinquish_lease", relinquishLease ? "true" : "false" }
                        };

                        // add optional fields - available only when interface can "Release"
                        if (netInterface.dhcpReleaseFormIf != null)
                        {
                            formParams.Add("if", netInterface.dhcpReleaseFormIf);
                        }
                        if (netInterface.dhcpReleaseFormIpV != null)
                        {
                            formParams.Add("ipv", netInterface.dhcpReleaseFormIpV);
                        }

                        request.Content = new FormUrlEncodedContent(formParams);
                        var response = await context.SendAsync(request, true); // expect 302

                        if (response.StatusCode == HttpStatusCode.Found)
                        {
                            // follow-through with reloading content
                            if (
                                response.Headers.Location != null &&
                                response.Headers.Location.OriginalString == "status_interfaces.php"
                                )
                            {
                                // re-request fresh page
                                parsePageContent(await GetStatusInterfacesContent(context));
                            }
                        }
                        else
                        {
                            throw new InvalidOperationException("Expected pfSense to 302 redirect me to status_interfaces.php but that did not happen, this is a bug");
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException("Missing required form parameters for DHCP Release form, this is a bug");
                    }
                }
                else
                {
                    throw new InvalidOperationException("Interface is not a DHCP Interface or its status is not Up");
                }
            }
            else
            {
                throw new InvalidOperationException("Unknown interface provided, the Interface object must come from the Interfaces list of this class instance");
            }
        }