{"id":107700,"date":"2023-01-12T07:00:00","date_gmt":"2023-01-12T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=107700"},"modified":"2023-01-11T19:06:53","modified_gmt":"2023-01-12T03:06:53","slug":"20230112-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20230112-00\/?p=107700","title":{"rendered":"How should I interpret the various values of <CODE>NLM_CONNECTIVITY<\/CODE>?"},"content":{"rendered":"<p>The <code>NLM_<wbr \/>CONNECTIVITY<\/code> flags enumeration describes what types of network connectivity are available, as far as the networking infrastructure can tell.<\/p>\n<p>Mind you, network connectivity is a hazy concept, because whether a particular endpoint can be reached is dependent not only on the configuration of the local system, but also on the configuration of every machine between you and the endpoint, and those configurations can change at any time. A hunter <a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20211019-00\/?p=105811\"> accidentally damages a power line<\/a> and suddenly you lose connection to a server. The system won&#8217;t know about this until you try to contact that server.<\/p>\n<p>Even for the state of the local system, it takes time for the system to re-evaluate the network connectivity after a change in configuration (such as an unplugged network cable), so you have to accept that the values you receive are based on the most recent information available, but that information may be in flux. And of course there are the shenanigans noted above.<\/p>\n<p>The networking folks gave me this breakdown of what the flags mean and how apps should deal with them.<\/p>\n<table class=\"cp3\" style=\"border-collapse: collapse;\" border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<th>Flag<\/th>\n<th>Meaning<\/th>\n<th>Recommendation<\/th>\n<\/tr>\n<tr>\n<td nowrap=\"nowrap\"><code>DISCONNECTED<\/code><\/td>\n<td>No network interface detects any network.<\/td>\n<td rowspan=\"2\">Treat as offline.<\/td>\n<\/tr>\n<tr>\n<td nowrap=\"nowrap\"><code>NOTRAFFIC<\/code><\/td>\n<td>An interface is connected, but it cannot send or receive network traffic.<\/td>\n<\/tr>\n<tr>\n<td nowrap=\"nowrap\"><code>SUBNET<\/code><\/td>\n<td rowspan=\"2\">An interface has been configured to send traffic, but the system cannot confirm Internet connectivity.<\/td>\n<td rowspan=\"2\">Make one attempt to contact service.<\/td>\n<\/tr>\n<tr>\n<td nowrap=\"nowrap\"><code>LOCALNETWORK<\/code><\/td>\n<\/tr>\n<tr>\n<td nowrap=\"nowrap\"><code>INTERNET<\/code><\/td>\n<td>The system has confirmed access<br \/>\nto Microsoft Internet sites.<\/td>\n<td>Treat as fully online.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>In the case of <code>SUBNET<\/code> or <code>LOCALNETWORK<\/code>, you can make one attempt to contact your Internet service even though Windows doesn&#8217;t think it&#8217;s going to work. This deals with the case where people employ shenanigans to prevent Windows from detecting Internet connectivity, such as blocking access to the <code>msftconnecttest.com<\/code> site, or to all Microsoft-owned IP addresses.<\/p>\n<p>The <code>IsConnected<\/code> property considers your network to be connected if it is connected to a <code>LOCALNETWORK<\/code> or <code>INTERNET<\/code>. The <code>IsConnected\u00adTo\u00adInternet<\/code> property requires <code>INTERNET<\/code>.<\/p>\n<p>If the system is trapped behind a captive portal, it will report itself as <code>LOCALNETWORK<\/code>. To identify the captive portal case specifically, call <code>INetwork\u00adList\u00adManager::<wbr \/>Get\u00adNetworks<\/code> and use the <code>IEnum\u00adNetworks<\/code> to enumerate all the <code>INetwork<\/code> objects. <a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/win32\/api\/netlistmgr\/nn-netlistmgr-inetwork\"> Query each <code>INetwork<\/code> for <code>IProperty\u00adBag<\/code><\/a> and check the <code>NA_<wbr \/>Internet\u00adConnectivity\u00adV4<\/code> and <code>NA_<wbr \/>Internet\u00adConnectivity\u00adV6<\/code> properties. If either one has the <a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/win32\/api\/netlistmgr\/ne-netlistmgr-nlm_internet_connectivity\"> <code>NLM_<wbr \/>INTERNET_<wbr \/>CONNECTIVITY_<wbr \/>WEB\u00adHIJACK<\/code><\/a> flag set, then you are trapped in a captive portal.<\/p>\n<p>Another way to check whether you&#8217;re stuck in a captive portal is to call <code>Connection\u00adProfile.Get\u00adNetwork\u00adConnectivity\u00adLevel<\/code> and check for <code>Constrained\u00adInternet\u00adAccess<\/code>, which is the name <code>Network\u00adConnectivity\u00adLevel<\/code> gives to being stuck in a captive portal.<\/p>\n<p>(I&#8217;m sorry it&#8217;s so complicated, but networking is complicated.)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Different levels of connectedness.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-107700","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Different levels of connectedness.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/107700","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=107700"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/107700\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=107700"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=107700"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=107700"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}