11

I need to identify if a request comes from Internet or Intranet using either client-side or server-side.

The problem I'm trying to solve is: our web site can be accessed from internet and intranet. The intranet user (user inside company), does not have access to internet. We are using Google Anylitics, when intranet user access the page, the page take so long to upload because it tries to download (ga) JavaScript file generated from Google.

Any solution?

Jehof
  • 34,674
  • 10
  • 123
  • 155
asalhani
  • 145
  • 1
  • 1
  • 8

4 Answers4

16

You can check the ip address of a user. Private ip4 address always start with either 10., or 172., or 192.* ... more info on private networks here.

You can also make Google Analytics load Asynchronous.

***************** UPDATE - PLEASE READ *************************************

As @igor-turman has correctly pointed out, that only a portion of the "172" and the "192" address ranges are designated for private use. The remaining ip addresses starting with 172 and 192 ARE PUBLIC.

Here is the regex expression to check for private IP addresses:

(^192\.168\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])$)|(^172\.([1][6-9]|[2][0-9]|[3][0-1])\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])$)|(^10\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])$)

You can test this regex on regexpal.com here.

autonomatt
  • 4,393
  • 4
  • 27
  • 36
  • 4
    Not correct. Only portions of 172.* and 192.* ranges are designated as private ones: https://www.arin.net/knowledge/address_filters.html – Igor Turman Oct 01 '14 at 18:18
  • 2
    @autonomatt, you should update or remove your answer as people upvoting are being misled by it and it can result in big trouble if they just trust your answer without studying the details. – Fabio Milheiro Sep 25 '17 at 16:40
  • 1
    Can you share similar regex for IPV6. – AMIT SHELKE Mar 27 '19 at 05:59
  • It is not clear if the updated regex is dealing correctly to exclude the public IP addresses in the 172.* and 192.* ranges. None if this is possible at all. – zion Sep 06 '19 at 12:01
  • 1
    You're using [0-2][0-5][0-5] to test 3 digit entries (100-255). This fails for 3 digit numbers that contain a number higher than 5 e.g. 189 – Rune Vejen Petersen Mar 23 '21 at 08:48
4

This is how I would do the ip check:

string ipString = System.Web.HttpContext.Current.Request.UserHostAddress;
byte[] ipBytes = System.Net.IPAddress.Parse(ipString).GetAddressBytes();
int ip = System.BitConverter.ToInt32(ipBytes, 0);

// your network ip range
string ipStringFrom = "192.168.1.0";
byte[] ipBytesFrom = System.Net.IPAddress.Parse(ipStringFrom).GetAddressBytes();
int ipFrom = System.BitConverter.ToInt32(ipBytesFrom, 0);

string ipStringTo = "192.168.1.255";
byte[] ipBytesTo= System.Net.IPAddress.Parse(ipStringTo).GetAddressBytes();
int ipTo = System.BitConverter.ToInt32(ipBytesFrom, 0);

bool clientIsOnLAN = ipFrom >= ip && ip <= ipTo;

If you have multiple subnets, just do the same for them (from, to), then add to the bool condition above. I just realized that, in your case, the above may be an overkill.

Alternatively, for you, it might be as simple as:

bool isOnLAN = System.Web.HttpContext.Current.Request.UserHostAddress.StartsWith("192.168.1.")
  • This example does not pass unit tests for the lower ends of the correct private network ranges (e.g. 192.168.0.0, 10.0.0.0 etc.). So, it is not valid. Also, it has typo - ipBytesFrom repeats in the "To" block. – Igor Turman Oct 01 '14 at 18:23
  • 1
    Check out this solution: http://stackoverflow.com/a/11628125/800165. It does the job and passes unit tests – Igor Turman Oct 01 '14 at 18:34
  • Valid if user connect with VPN ? – Kiquenet Apr 30 '21 at 12:07
1

Necromancing:
None of the answers are good or correct.
You can convert the IP (IPv4 only - IPv6 is UInt128) into a UInt32 value, and then you can check if the requesting IP is somewhere in the private IP ranges:

e.g. you can use that to set the cookies to "Secure", if it's not intranet.

For Each thisCookie As System.Web.HttpCookie In response.Cookies
    thisCookie.HttpOnly = True

    Dim ipString As String = System.Web.HttpContext.Current.Request.UserHostAddress

    If Not IPv4Info.IsPrivateIp(ipString) Then
        thisCookie.Secure = True
    End If

Next thisCookie

VB.NET Class, which you can convert into C# yourselfs (http://converter.telerik.com)

Public Class IPv4Info


    Private Class IPv4Range
        Public RangeStart As UInt32
        Public RangeEnd As UInt32
    End Class


    ' https://en.wikipedia.org/wiki/Private_network
    ' https://tools.ietf.org/html/rfc1918
    ' 192.168.0.0 - 192.168.255.255 (65,536 IP addresses)
    ' 172.16.0.0 - 172.31.255.255 (1,048,576 IP addresses)
    ' 10.0.0.0 - 10.255.255.255 (16,777,216 IP addresses)

    Private Shared Rng127 As IPv4Range = New IPv4Range() With {.RangeStart = GetIpNum("127.0.0.0"), .RangeEnd = GetIpNum("127.255.255.255")}
    Private Shared Rng192 As IPv4Range = New IPv4Range() With {.RangeStart = GetIpNum("192.168.0.0"), .RangeEnd = GetIpNum("192.168.255.255")} ' CIDR: 192.168.0.0/16 (255.255.0.0) 
    Private Shared Rng172 As IPv4Range = New IPv4Range() With {.RangeStart = GetIpNum("172.16.0.0"), .RangeEnd = GetIpNum("172.31.255.255")} ' CIDR: 172.16.0.0/12 (255.240.0.0)
    Private Shared Rng10 As IPv4Range = New IPv4Range() With {.RangeStart = GetIpNum("10.0.0.0"), .RangeEnd = GetIpNum("10.255.255.255")} ' CIDR: 10.0.0.0/8 (255.0.0.0)


    ' http://stackoverflow.com/questions/36831/how-do-you-parse-an-ip-address-string-to-a-uint-value-in-c
    Public Shared Function GetIpNum(ipString As String) As UInt32
        Dim ipAddress__1 As System.Net.IPAddress = System.Net.IPAddress.Parse("some.ip.address")
        Dim ipBytes As Byte() = ipAddress__1.GetAddressBytes()
        Dim ip As UInt32 = CUInt(ipBytes(0)) << 24
        ip += CUInt(ipBytes(1)) << 16
        ip += CUInt(ipBytes(2)) << 8
        ip += CUInt(ipBytes(3))

        Return ip
    End Function


    Public Shared Function isIn127(ipString As String) As Boolean
        Dim ip As UInt32 = GetIpNum(ipString)
        Return isIn127(ip)
    End Function


    Public Shared Function isIn127(x As UInt32) As Boolean
        If x >= Rng127.RangeStart AndAlso x <= Rng127.RangeEnd Then
            Return True
        End If

        Return False
    End Function



    Public Shared Function isIn192(ipString As String) As Boolean
        Dim ip As UInt32 = GetIpNum(ipString)
        Return isIn192(ip)
    End Function


    Public Shared Function isIn192(x As UInt32) As Boolean
        If x >= Rng192.RangeStart AndAlso x <= Rng192.RangeEnd Then
            Return True
        End If

        Return False
    End Function


    Public Shared Function isIn172(ipString As String) As Boolean
        Dim ip As UInt32 = GetIpNum(ipString)
        Return isIn172(ip)
    End Function


    Public Shared Function isIn172(x As UInt32) As Boolean
        If x >= Rng172.RangeStart AndAlso x <= Rng172.RangeEnd Then
            Return True
        End If

        Return False
    End Function


    Public Shared Function isIn10(ipString As String) As Boolean
        Dim ip As UInt32 = GetIpNum(ipString)
        Return isIn10(ip)
    End Function


    Public Shared Function isIn10(x As UInt32) As Boolean
        If x >= Rng10.RangeStart AndAlso x <= Rng10.RangeEnd Then
            Return True
        End If

        Return False
    End Function

    ' string ipString = System.Web.HttpContext.Current.Request.UserHostAddress;
    Public Shared Function IsPrivateIp(ipString As String) As Boolean
        Dim ip As UInt32 = GetIpNum(ipString)

        Return IsPrivateIp(ip)
    End Function


    Public Shared Function IsPrivateIp(ip As UInt32) As Boolean

        If isIn127(ip) OrElse isIn192(ip) OrElse isIn172(ip) OrElse isIn10(ip) Then
            Return True
        End If

        Return False
    End Function


End Class

Note: For doing this with UInt128, there's a good implementation of UInt128 in NaCl.NET.

Stefan Steiger
  • 78,642
  • 66
  • 377
  • 442
0

Use the Request.UserHostAddress property to determine whether the request came from a public or private network

Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206