Detecting Internet on macOS

  1. 7 weeks ago

    John M

    Feb 13 Pre-Release Testers, Xojo Pro New York / New Jersey

    My app (Lightwright) needs to know whether or not the user has internet access. I've been doing it using a Shell to ping Google. In this code, "Me" is a subclass of Shell:

    Me.ExecuteMode=Shell.ExecuteModes.ASynchronous

    -------------
    Dim Astr as String = "ping -c 2 google.com" Me.Execute(Astr)-------------

    In the .DataAvailable event, I check the .Result property to see if it contains "google", which it would if it was able to connect to Google
    If .Result contains "cannot resolve" or "could not find host" or "unknown host", then I know it failed. This works great for 99% of my users, but recently there have been a few where it fails.

    Today I had a really good bug report on this from, which said:

    "I have an internet connection (en8, wired, through a USB-C dock, is primary in service order, then WiFi, en0). Both are working correctly, but Lightwright says it doesn't have an internet connection. I tried turning WiFi off to limit to just one wired connection, same error persists. For reference, I've attached my ifconfig report. Is it possible that Lightwright isn't fully enumerating all connections and checking for status active?"

    I have no idea what an ifconfig report is, but here's a snippet:

    lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
    options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>
    inet 127.0.0.1 netmask 0xff000000
    inet6 ::1 prefixlen 128
    inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
    nd6 options=201<PERFORMNUD,DAD>
    gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
    stf0: flags=0<> mtu 1280
    XHC20: flags=0<> mtu 0
    XHC1: flags=0<> mtu 0
    XHC0: flags=0<> mtu 0
    VHC128: flags=0<> mtu 0
    en5: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    ether ac:de:48:00:11:22
    inet6 fe80::aede:48ff:fe00:1122%en5 prefixlen 64 scopeid 0x8
    nd6 options=201<PERFORMNUD,DAD>
    media: autoselect (100baseTX <full-duplex>)
    status: active
    ap1: flags=8802<BROADCAST,SIMPLEX,MULTICAST> mtu 1500
    ether 3a:f9:d3:dd:b5:ec
    media: autoselect
    status: inactive
    en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    ether 38:f9:d3:dd:b5:ec
    inet6 fe80::102c:8b4c:5ea6:808f%en0 prefixlen 64 secured scopeid 0xa
    inet 10.120.20.63 netmask 0xfffffc00 broadcast 10.120.23.255
    nd6 options=201<PERFORMNUD,DAD>
    media: autoselect
    status: active

    Does anyone have a clue why ping doesn't work for this user? is there a better way to test for a connection? I could just try to download something from a known location (as if web pages never move), would that be more reliable?

    Thanks!

    - John

  2. Tim P

    Feb 13 Pre-Release Testers, Xojo Pro Rochester, NY

    @John M Does anyone have a clue why ping doesn't work for this user?

    It would be valuable to know what the response your app is getting actually is. The user could try ping in terminal, but the result could be different. Both are valuable bits of information though.

    @John McKernon is there a better way to test for a connection?

    Using the framework sockets can cause unavoidable hangs in some situations. I think this ping approach is pretty decent unless we find a problem with Shell. Do you know if the user is running Catalina?

  3. Julian S

    Feb 13 Pre-Release Testers, Xojo Pro UK

    Did you ask the user to perform the same ping in terminal and did it work? Do you know if they block any connections from your app?

    If they block ping (ICMP) with little snitch you'll get a "Host is down" (at least thats what I see in a quick Mojave test I just did), I'm not sure if you check for that? I'm not sure what you get if ICMP is blocked at the modem as I don't want to tweak that just before going to bed, this might be a similar message.

    If you let us know why you need to check for an internet connection we might be able to suggest an alternate method that could be less prone to being blocked/stopped. Like, is there a reason you check for internet, e.g. for connection to your update service or licence service? If you check for a connection to a web service, it might just be better to try that connection and catch the failure.

  4. Valdemar D

    Feb 13 Pre-Release Testers, Xojo Pro Europe ( France, Paris )

    I use this code to check internet connection :

    Public Function CheckOnline() as Boolean
      Dim ret As Boolean = False
      Dim sh As New Shell 
      
      sh.Mode = 2 
      
      If TargetWin32 Then 
        sh.Timeout = -1 
        sh.Execute "ping -w 5000 -n 1 www.google.com"
      Else 
        sh.Execute "ping -n -q -W 5 -c 1 www.google.com"
      End If 
      Do 
        App.DoEvents(25)
      Loop Until Not sh.IsRunning 
      If sh.Errorcode=0 Then  // success
        ret = True
      End If 
      
      Return ret
      
    End Function
  5. Jean-Yves P

    Feb 13 Pre-Release Testers, Xojo Pro Europe (France, Besançon)
    Edited 7 weeks ago

    https://forum.xojo.com/36891-best-way-to-determine-internet-connection-vote-advice

    the result is :

    Dim http As New TCPSocket
    http.Address = "www.apple.com"
    http.port = 80
    http.Connect
    dim okapple as Boolean = (http.LastErrorCode = 0)
    http.close

    works on any platform.

  6. Valdemar D

    Feb 13 Pre-Release Testers, Xojo Pro Europe ( France, Paris )

    But with your solution @Jean-YvesPochez , you have to wait the time out. And it can freeze you app for too long time. doing a ping with command shell can be done in a few

  7. Jean-Yves P

    Feb 14 Pre-Release Testers, Xojo Pro Europe (France, Besançon)

    @Valdemar Dnbsp;SOUSA But with your solution @Jean-YvesPochez , you have to wait the time out. And it can freeze you app for too long time. doing a ping with command shell can be done in a few

    right, but I recall that using a shell command does prevent you from selling through mac app store ?

  8. Jürg O

    Feb 14 Pre-Release Testers, Xojo Pro

    @Jean-YvesPochez http.port = 80
    works on any platform.

    Doesn't macOS require Entitlements or whatever to connect to "insecure http websites"?
    Or does that only apply when creating a http request and does not apply to TCPSocket?

  9. Emile S

    Feb 14 Europe (France, Strasbourg)

    What will happens if the service (google.com , www.apple.com ) is down ?

  10. Thomas E

    Feb 14 Pre-Release Testers

    @Emile S What will happens if the service (google.com , www.apple.com ) is down ?

    The world ends :P

  11. @John M — Maybe his network or a firewall just blocks ICMP traffic so ping does not work.

  12. John M

    Feb 15 Pre-Release Testers, Xojo Pro New York / New Jersey

    I heard back from him tonight, he's on macOS 10.14.6.

    Since he's obviously pretty savvy, I asked him to try using Terminal to send some pings and see what they return - or not.

    I'm also asking him if they're blocking ICMP traffic. He works at a school which might be very locked down...

  13. Norman P

    Feb 16 Pre-Release Testers, Xojo Pro outside enjoying the fresh air

    Would seem this is the righ way to test things

    https://developer.apple.com/documentation/systemconfiguration/scnetworkreachability?language=objc

  14. Tomas J

    Feb 17 Pre-Release Testers, Xojo Pro Europe (Germany)
    Edited 7 weeks ago

    Couple words on bad and unsecure programming habits:

    To ping a target is stupid, let me explain why. Firstly, in normal secure networks - not those !@#$% ones - access to the internet is controlled. At least there is some sort of transparent or non transparent webproxy blocking everything outgoing. Secondly any IDS/IPS will be triggered immediatly when inside the secured network any hosts or software starts pinging around. In best case the ping is just blocked, in worst cases the pinging host is banned from the internal network. Last but not least: How to explain it to the customer that your software is contacting Google or Apple when a personal firewall (e.g. LittleSnitch) pops up?

    As a rule of thumb:

    1. Do not access the web without consent or at least without prior information.
    2. Dont use PING/ICMP better use http/https with system default's proxy settings or as Norman said, native OS API.
    3. Don't use Google or Apple. Don't you have an own Website?

    @Emile Schwarz What will happens if the service (google.com , www.apple.com ) is down ?

    The free internet returns...

  15. Julian S

    Feb 17 Pre-Release Testers, Xojo Pro UK

    @Norman P Would seem this is the righ way to test things

    https://developer.apple.com/documentation/systemconfiguration/scnetworkreachability?language=objc

    "Reachability does not guarantee that the data packet will actually be received by the host." so pretty pointless for a web based check, much like similar routines on windows.

  16. Norman P

    Feb 17 Pre-Release Testers, Xojo Pro outside enjoying the fresh air

    A ping is also not guaranteed to reach the intended host
    It can / could be blocked as Tomas already noted

  17. John M

    Feb 17 Pre-Release Testers, Xojo Pro New York / New Jersey
    Edited 7 weeks ago

    @Tomas J Do not access the web without consent or at least without prior information.
    Dont use PING/ICMP better use http/https with system default's proxy settings or as Norman said, native OS API.
    Don't use Google or Apple. Don't you have an own Website?

    Users are made well aware that the app is going to access the internet if it has the chance, there are multiple features that take advantage of it (though it's not required). I went the ping route because many people on this site appear to be using and recommending it. I can try the APIs, though my experience with them is essentially zero. Still worth a try.

    And yes, I have a web site, but this app may well outlive me (this is its 40th year, my 68th), it would be best if it didn't rely on my web site being available.

    Thanks!

  18. Tomas J

    Feb 17 Pre-Release Testers, Xojo Pro Europe (Germany)
    Edited 7 weeks ago

    Just another thought: Think about what your customer, a pentester, security or data protection auditor will see. A piece of software trying to communicate with a 3rd party without consent, in this case with the biggest data violator, Google. None of them knows that you're just pinging them. If you want to check internet connectivity than please check this with the hosts you really need.

    @Norman Palardy A ping is also not guaranteed to reach the intended host
    It can / could be blocked as Tomas already noted

    You remind me to the fact, that it not only can be done by the customer but by the site operator aswell in order to reduce the background noise. Try to ping my website jakobssystems.net , you will fail. And in addition to that. For my internal Cloud Host cloud.jakobssystems.de I am blocking any regions with GeoIP filters where I know, that I wont do any business there. Basically everything outside and south and east of Europe. This reduces the attack surface significantly and improves bandwith for my cloud host next to me in my office which is only connected with 20 MBit with the internet.

    @John McKernon And yes, I have a web site, but this app may well outlive me (this is its 40th year, my 68th), it would be best if it didn't rely on my web site being available.

    Well the possibility that Google will be among us in, let's say, 10-20 years is equal with the chance your site will be there. Just think 20 years back. Do Altavista, Lycos or Yahoo exist - the big search engines of the 90ies? Well Yahoo might still be there but it's more like a zombie, dying a long till really vanished. But you and me are still here, heck we are talking with each other ;-)

  19. David C

    Feb 18 Pre-Release Testers, Xojo Pro, XDC Speakers Derby, ITM

    Here is one more for the list:

    Return (Len(DNSNameToAddressMBS("www.google.com")) > 0)
  20. Newer ›

or Sign Up to reply!