{"id":103673,"date":"2020-04-15T07:00:00","date_gmt":"2020-04-15T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=103673"},"modified":"2020-04-15T07:32:31","modified_gmt":"2020-04-15T14:32:31","slug":"20200415-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20200415-00\/?p=103673","title":{"rendered":"When I ask the <CODE>GetIpAddrTable<\/CODE> function to sort the results, how are they sorted?"},"content":{"rendered":"<p>A customer had a question about the way the <code>GetIpAddrTable<\/code> function sorts the results. The documentation says that if you pass <code>TRUE<\/code> as the <code>bOrder<\/code> parameter, then the mapping table will be sorted upon return.<\/p>\n<p>What exactly is this sorting order?<\/p>\n<p>The customer observed that in practice, they got the IP addresses in this order: Public IP addresses, then internal addresses, and then local addresses. They were interested in obtaining the public IP address, so they just asked for the results to be sorted and the grabbed the first one.<\/p>\n<p>That worked great until one day, they grabbed the first sorted address and got the local address 127.0.0.1. Did this mean that the system didn&#8217;t have any public IP addresses? The customer is trying to figure out why there was no public address, or at least no public address that the <code>GetIpAddrTable<\/code> function could find.<\/p>\n<p>The problem is that their assumption wasn&#8217;t supported by the documentation. The documentation says that the <code>bOrder<\/code> parameter controls &#8220;whether the returned mapping table should be sorted in ascending order by IPv4 address.&#8221;<\/p>\n<p>The sorting is done <u>by IPv4 address<\/u>, not by scope or availability or subnet or routing or broadcast. Specifically, the sorting is done in lexicographical order by the IPv4 address in network byte order.<\/p>\n<p>The following table lists the IPv4 addresses in sorted order (not to scale):<\/p>\n<table class=\"cp3\" style=\"border-collapse: collapse; text-align: center;\" border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<th>Dotted notation<\/th>\n<th>Network byte order<\/th>\n<th><tt>dwAddress<\/tt><\/th>\n<th>Notes<\/th>\n<\/tr>\n<tr>\n<td>0.0.0.0<\/td>\n<td><tt>00 00 00 00<\/tt><\/td>\n<td><tt>0x00000000<\/tt><\/td>\n<td rowspan=\"5\" valign=\"center\">Local<\/td>\n<\/tr>\n<tr>\n<td>0.0.0.1<\/td>\n<td><tt>00 00 00 01<\/tt><\/td>\n<td><tt>0x01000000<\/tt><\/td>\n<\/tr>\n<tr>\n<td>\u22ee<\/td>\n<td>\u22ee<\/td>\n<td>\u22ee<\/td>\n<\/tr>\n<tr>\n<td>0.255.255.254<\/td>\n<td><tt>00 FF FF FE<\/tt><\/td>\n<td><tt>0xFEFFFF00<\/tt><\/td>\n<\/tr>\n<tr>\n<td>0.255.255.255<\/td>\n<td><tt>00 FF FF FF<\/tt><\/td>\n<td><tt>0xFFFFFF00<\/tt><\/td>\n<\/tr>\n<tr>\n<td>1.0.0.0<\/td>\n<td><tt>01 00 00 00<\/tt><\/td>\n<td><tt>0x00000001<\/tt><\/td>\n<td rowspan=\"4\" valign=\"center\">Public<\/td>\n<\/tr>\n<tr>\n<td>1.0.0.1<\/td>\n<td><tt>01 00 00 01<\/tt><\/td>\n<td><tt>0x01000001<\/tt><\/td>\n<\/tr>\n<tr>\n<td>\u22ee<\/td>\n<td>\u22ee<\/td>\n<td>\u22ee<\/td>\n<\/tr>\n<tr>\n<td>9.255.255.255<\/td>\n<td><tt>09 FF FF FF<\/tt><\/td>\n<td><tt>0xFFFFFF09<\/tt><\/td>\n<\/tr>\n<tr>\n<td>10.0.0.0<\/td>\n<td><tt>0A 00 00 00<\/tt><\/td>\n<td><tt>0x0000000A<\/tt><\/td>\n<td rowspan=\"4\" valign=\"center\">Private<\/td>\n<\/tr>\n<tr>\n<td>10.0.0.1<\/td>\n<td><tt>0A 00 00 01<\/tt><\/td>\n<td><tt>0x0100000A<\/tt><\/td>\n<\/tr>\n<tr>\n<td>\u22ee<\/td>\n<td>\u22ee<\/td>\n<td>\u22ee<\/td>\n<\/tr>\n<tr>\n<td>10.255.255.255<\/td>\n<td><tt>0A FF FF FF<\/tt><\/td>\n<td><tt>0xFFFFFF0A<\/tt><\/td>\n<\/tr>\n<tr>\n<td>11.0.0.0<\/td>\n<td><tt>0B 00 00 00<\/tt><\/td>\n<td><tt>0x0000000B<\/tt><\/td>\n<td rowspan=\"4\" valign=\"center\">Public<br \/>\n(mostly)<\/td>\n<\/tr>\n<tr>\n<td>11.0.0.1<\/td>\n<td><tt>0B 00 00 01<\/tt><\/td>\n<td><tt>0x0100000B<\/tt><\/td>\n<\/tr>\n<tr>\n<td>\u22ee<\/td>\n<td>\u22ee<\/td>\n<td>\u22ee<\/td>\n<\/tr>\n<tr>\n<td>126.255.255.255<\/td>\n<td><tt>7E FF FF FF<\/tt><\/td>\n<td><tt>0xFFFFFF7E<\/tt><\/td>\n<\/tr>\n<tr>\n<td>127.0.0.0<\/td>\n<td><tt>7F 00 00 00<\/tt><\/td>\n<td><tt>0x0000007F<\/tt><\/td>\n<td rowspan=\"4\" valign=\"center\">Loopback<\/td>\n<\/tr>\n<tr>\n<td>127.0.0.1<\/td>\n<td><tt>7F 00 00 01<\/tt><\/td>\n<td><tt>0x0100007F<\/tt><\/td>\n<\/tr>\n<tr>\n<td>\u22ee<\/td>\n<td>\u22ee<\/td>\n<td>\u22ee<\/td>\n<\/tr>\n<tr>\n<td>127.255.255.255<\/td>\n<td><tt>7F FF FF FF<\/tt><\/td>\n<td><tt>0xFFFFFF7F<\/tt><\/td>\n<\/tr>\n<tr>\n<td>128.0.0.0<\/td>\n<td><tt>80 00 00 00<\/tt><\/td>\n<td><tt>0x00000080<\/tt><\/td>\n<td rowspan=\"4\" valign=\"center\">Public<br \/>\n(mostly)<\/td>\n<\/tr>\n<tr>\n<td>128.0.0.1<\/td>\n<td><tt>80 00 00 01<\/tt><\/td>\n<td><tt>0x01000080<\/tt><\/td>\n<\/tr>\n<tr>\n<td>\u22ee<\/td>\n<td>\u22ee<\/td>\n<td>\u22ee<\/td>\n<\/tr>\n<tr>\n<td>255.255.255.255<\/td>\n<td><tt>FF FF FF FF<\/tt><\/td>\n<td><tt>0xFFFFFFFF<\/tt><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Note that the areas marked &#8220;Public (mostly)&#8221; contain islands of private or other special addresses within them. The purpose of this list was not to break down the entire IPv4 address range. It was to highlight that lexicographical ordering by IPv4 address in network byte order has no relation to the nature of the address.<\/p>\n<p>I suspect what happened is that the company&#8217;s public IP address assignment moved from an address less than <code>127.0.0.0<\/code> to one greater than <code>128.0.0.0<\/code>, which means that <code>127.0.0.1<\/code> is now the numerically lowest IP address.<\/p>\n<p>The sorting performed by the <code>GetIpAddrTable<\/code> is purely numerical by IPv4 address. If you want to fish out your system&#8217;s public IP address, you&#8217;ll have to do your own filtering.<\/p>\n<p><b>Bonus chatter<\/b>: I listed IPv4 addresses like 0.0.0.1, even though 0.0.0.1 is strictly speaking <a href=\"https:\/\/tools.ietf.org\/html\/rfc1122#page-29\"> not a valid IPv4 address<\/a>. The <a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/win32\/winsock\/ipproto-ip-socket-options\"> <code>IP_MULTICAST_IF<\/code> socket option<\/a> uses values of this form to mean &#8220;Not an address, but an interface index.&#8221;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nothing particularly fancy. Just plain numerical order.<\/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-103673","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Nothing particularly fancy. Just plain numerical order.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/103673","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=103673"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/103673\/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=103673"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=103673"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=103673"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}