[asp.net] Getting the client IP address: REMOTE_ADDR, HTTP_X_FORWARDED_FOR, what else could be useful?

I've ported Grant Burton's PHP code to an ASP.Net static method callable against the HttpRequestBase. It will optionally skip through any private IP ranges.

public static class ClientIP
{
    // based on http://www.grantburton.com/2008/11/30/fix-for-incorrect-ip-addresses-in-wordpress-comments/
    public static string ClientIPFromRequest(this HttpRequestBase request, bool skipPrivate)
    {
        foreach (var item in s_HeaderItems)
        {
            var ipString = request.Headers[item.Key];

        if (String.IsNullOrEmpty(ipString))
            continue;

        if (item.Split)
        {
            foreach (var ip in ipString.Split(','))
                if (ValidIP(ip, skipPrivate))
                    return ip;
        }
        else
        {
            if (ValidIP(ipString, skipPrivate))
                return ipString;
        }
    }

    return request.UserHostAddress;
}

private static bool ValidIP(string ip, bool skipPrivate)
{
    IPAddress ipAddr;

    ip = ip == null ? String.Empty : ip.Trim();

    if (0 == ip.Length
        || false == IPAddress.TryParse(ip, out ipAddr)
        || (ipAddr.AddressFamily != AddressFamily.InterNetwork
            && ipAddr.AddressFamily != AddressFamily.InterNetworkV6))
        return false;

    if (skipPrivate && ipAddr.AddressFamily == AddressFamily.InterNetwork)
    {
        var addr = IpRange.AddrToUInt64(ipAddr);
        foreach (var range in s_PrivateRanges)
        {
            if (range.Encompasses(addr))
                return false;
        }
    }

    return true;
}

/// <summary>
/// Provides a simple class that understands how to parse and
/// compare IP addresses (IPV4) ranges.
/// </summary>
private sealed class IpRange
{
    private readonly UInt64 _start;
    private readonly UInt64 _end;

    public IpRange(string startStr, string endStr)
    {
        _start = ParseToUInt64(startStr);
        _end = ParseToUInt64(endStr);
    }

    public static UInt64 AddrToUInt64(IPAddress ip)
    {
        var ipBytes = ip.GetAddressBytes();
        UInt64 value = 0;

        foreach (var abyte in ipBytes)
        {
            value <<= 8;    // shift
            value += abyte;
        }

        return value;
    }

    public static UInt64 ParseToUInt64(string ipStr)
    {
        var ip = IPAddress.Parse(ipStr);
        return AddrToUInt64(ip);
    }

    public bool Encompasses(UInt64 addrValue)
    {
        return _start <= addrValue && addrValue <= _end;
    }

    public bool Encompasses(IPAddress addr)
    {
        var value = AddrToUInt64(addr);
        return Encompasses(value);
    }
};

private static readonly IpRange[] s_PrivateRanges =
    new IpRange[] { 
            new IpRange("0.0.0.0","2.255.255.255"),
            new IpRange("10.0.0.0","10.255.255.255"),
            new IpRange("127.0.0.0","127.255.255.255"),
            new IpRange("169.254.0.0","169.254.255.255"),
            new IpRange("172.16.0.0","172.31.255.255"),
            new IpRange("192.0.2.0","192.0.2.255"),
            new IpRange("192.168.0.0","192.168.255.255"),
            new IpRange("255.255.255.0","255.255.255.255")
    };


/// <summary>
/// Describes a header item (key) and if it is expected to be 
/// a comma-delimited string
/// </summary>
private sealed class HeaderItem
{
    public readonly string Key;
    public readonly bool Split;

    public HeaderItem(string key, bool split)
    {
        Key = key;
        Split = split;
    }
}

// order is in trust/use order top to bottom
private static readonly HeaderItem[] s_HeaderItems =
    new HeaderItem[] { 
            new HeaderItem("HTTP_CLIENT_IP",false),
            new HeaderItem("HTTP_X_FORWARDED_FOR",true),
            new HeaderItem("HTTP_X_FORWARDED",false),
            new HeaderItem("HTTP_X_CLUSTER_CLIENT_IP",false),
            new HeaderItem("HTTP_FORWARDED_FOR",false),
            new HeaderItem("HTTP_FORWARDED",false),
            new HeaderItem("HTTP_VIA",false),
            new HeaderItem("REMOTE_ADDR",false)
    };
}

Examples related to asp.net

RegisterStartupScript from code behind not working when Update Panel is used You must add a reference to assembly 'netstandard, Version=2.0.0.0 No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization How to use log4net in Asp.net core 2.0 Visual Studio 2017 error: Unable to start program, An operation is not legal in the current state How to create roles in ASP.NET Core and assign them to users? How to handle Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause() ASP.NET Core Web API Authentication Could not load file or assembly 'CrystalDecisions.ReportAppServer.CommLayer, Version=13.0.2000.0 WebForms UnobtrusiveValidationMode requires a ScriptResourceMapping for jquery

Examples related to http

Access blocked by CORS policy: Response to preflight request doesn't pass access control check Axios Delete request with body and headers? Read response headers from API response - Angular 5 + TypeScript Android 8: Cleartext HTTP traffic not permitted Angular 4 HttpClient Query Parameters Load json from local file with http.get() in angular 2 Angular 2: How to access an HTTP response body? What is HTTP "Host" header? Golang read request body Angular 2 - Checking for server errors from subscribe

Examples related to http-headers

Set cookies for cross origin requests Adding a HTTP header to the Angular HttpClient doesn't send the header, why? Passing headers with axios POST request What is HTTP "Host" header? CORS error :Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response Using Axios GET with Authorization Header in React-Native App Axios get access to response header fields Custom header to HttpClient request Send multipart/form-data files with angular using $http Best HTTP Authorization header type for JWT

Examples related to ip

Can't access 127.0.0.1 Correct way of getting Client's IP Addresses from http.Request How to get the IP address of the docker host from inside a docker container How to access site through IP address when website is on a shared host? How to change proxy settings in Android (especially in Chrome) What is the difference between 0.0.0.0, 127.0.0.1 and localhost? socket.error:[errno 99] cannot assign requested address and namespace in python Get client IP address via third party web service Getting IP address of client IIS - can't access page by ip address instead of localhost

Examples related to ip-address

how to get the ipaddress of a virtual box running on local machine How to get ip address of a server on Centos 7 in bash How to extract IP Address in Spring MVC Controller get call? Can You Get A Users Local LAN IP Address Via JavaScript? Get the client IP address using PHP Express.js: how to get remote client address Identifying country by IP address Which terminal command to get just IP address and nothing else? How to find Port number of IP address? C# IPAddress from string