Bug 198931 - Fix net/mDNSResponder errors "Tried to register a NetworkInterfaceInfo [IPv6] with invalid mask <C2><AB>ZERO ADDRESS<C2><BB>"
Summary: Fix net/mDNSResponder errors "Tried to register a NetworkInterfaceInfo [IPv6]...
Status: Closed FIXED
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: --- Affects Some People
Assignee: Po-Chuan Hsieh
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-03-26 18:53 UTC by Dimitry Andric
Modified: 2015-03-29 11:39 UTC (History)
1 user (show)

See Also:
bugzilla: maintainer-feedback? (sunpoet)


Attachments
Fix incorrect address family for IPv6 netmasks (1.30 KB, patch)
2015-03-26 18:53 UTC, Dimitry Andric
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dimitry Andric freebsd_committer 2015-03-26 18:53:36 UTC
Created attachment 154840 [details]
Fix incorrect address family for IPv6 netmasks

Since quite some time, net/mDNSResponder has been spamming my logs with the following type of errors, which occur whenever it is starting up:

Mar 25 21:33:26 tensor mDNSResponder: mDNS_RegisterInterface: Error! Tried to register a NetworkInterfaceInfo 2001:07B8:03A7:0000:020E:0CFF:FEA0:E4A2 with invalid mask <C2><AB>ZERO ADDRESS<C2><BB>
Mar 25 21:33:26 tensor mDNSResponder: mDNS_RegisterInterface: Error! Tried to register a NetworkInterfaceInfo 2001:07B8:03A7:0001:02D0:B7FF:FEA0:8C26 with invalid mask <C2><AB>ZERO ADDRESS<C2><BB>
Mar 25 21:33:26 tensor mDNSResponder: mDNS_RegisterInterface: Error! Tried to register a NetworkInterfaceInfo 2001:07B8:02FF:0146:0000:0000:0000:0002 with invalid mask <C2><AB>ZERO ADDRESS<C2><BB>
Mar 25 21:33:26 tensor mDNSResponder: mDNS_RegisterInterface: Error! Tried to register a NetworkInterfaceInfo 2001:07B8:03A7:0000:020E:0CFF:FEA0:E4A2 with invalid mask <C2><AB>ZERO ADDRESS<C2><BB>
Mar 25 21:33:26 tensor mDNSResponder: mDNS_RegisterInterface: Error! Tried to register a NetworkInterfaceInfo 2001:07B8:03A7:0001:02D0:B7FF:FEA0:8C26 with invalid mask <C2><AB>ZERO ADDRESS<C2><BB>
Mar 25 21:33:26 tensor mDNSResponder: mDNS_RegisterInterface: Error! Tried to register a NetworkInterfaceInfo 2001:07B8:02FF:0146:0000:0000:0000:0002 with invalid mask <C2><AB>ZERO ADDRESS<C2><BB>
Mar 25 21:33:26 tensor mDNSResponder: mDNS_RegisterInterface: Error! Tried to register a NetworkInterfaceInfo 2001:07B8:03A7:0000:020E:0CFF:FEA0:E4A2 with invalid mask <C2><AB>ZERO ADDRESS<C2><BB>
Mar 25 21:33:26 tensor mDNSResponder: mDNS_RegisterInterface: Error! Tried to register a NetworkInterfaceInfo 2001:07B8:03A7:0001:02D0:B7FF:FEA0:8C26 with invalid mask <C2><AB>ZERO ADDRESS<C2><BB>

And many more like this, usually for interfaces which have been configured with a global IPv6 address.  For each of these addresses, the prefixlen is actually 64, and therefore the mask is definitely not a "ZERO ADDRESS".

I did some digging, and found that mDNSPosix/mDNSUNP.c's get_ifi_info() function uses the SIOCGIFNETMASK_IN6 ioctl to retrieve the netmask:

   411          case AF_INET6:
   412              sinptr6 = (struct sockaddr_in6 *) &ifr->ifr_addr;
...
   430                      memset(&ifr6, 0, sizeof(ifr6));
   431                      memcpy(&ifr6.ifr_name,           &ifr->ifr_name, sizeof(ifr6.ifr_name          ));
   432                      memcpy(&ifr6.ifr_ifru.ifru_addr, &ifr->ifr_addr, sizeof(ifr6.ifr_ifru.ifru_addr));
   433                      if (ioctl(sockf6, SIOCGIFNETMASK_IN6, &ifr6) < 0) {
...
   449                      ifi->ifi_netmask = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in6));
   450                      if (ifi->ifi_netmask == NULL) goto gotError;
   451                      sinptr6 = (struct sockaddr_in6 *) &ifr6.ifr_ifru.ifru_addr;
   452                      memcpy(ifi->ifi_netmask, sinptr6, sizeof(struct sockaddr_in6));

However, it turns out that SIOCGIFNETMASK does *not* always fill the sin6_family field of the returned address: in some cases (I have not been able to determine what the cause is) it is returned as 0, even when sin6_len is correctly set to 28 for an IPv6 address.  There is already a comment about a similar situation for IPv4 addresses, a little earlier in the function:

   332          case AF_INET:
   333              sinptr = (struct sockaddr_in *) &ifr->ifr_addr;
...
   361                  sinptr = (struct sockaddr_in *) &ifrcopy.ifr_addr;
   362                  /* The BSD ioctls (including Mac OS X) stick some weird values in for sin_len and sin_family */
   363  #ifndef NOT_HAVE_SA_LEN
   364                  sinptr->sin_len    = sizeof(struct sockaddr_in);
   365  #endif
   366                  sinptr->sin_family = AF_INET;
   367                  memcpy(ifi->ifi_netmask, sinptr, sizeof(struct sockaddr_in));

Later on, the zero sin6_family field leads to a problem in mDNSPosix/mDNSPosix.c's SockAddrTomDNSAddr() function, because this checks the field, and *only* converts the adress to a mDNSAddr struct when the family is either AF_INET or AF_INET6.

Therefore, the SetupOneInterface() function results in a zeroed mask, and that leads to the above error messages.

The fix is to set sinptr6->sin6_family = AF_INET6 manually, analogous to the IPv4 situation.
Comment 1 commit-hook freebsd_committer 2015-03-28 18:51:00 UTC
A commit references this bug:

Author: sunpoet
Date: Sat Mar 28 18:50:48 UTC 2015
New revision: 382540
URL: https://svnweb.freebsd.org/changeset/ports/382540

Log:
  - Fix incorrect address family for IPv6 netmasks

  PR:		198931
  Submitted by:	dim

Changes:
  head/net/mDNSResponder/files/patch-mDNSPosix-mDNSUNP.c
Comment 2 Bartek Rutkowski freebsd_committer 2015-03-29 11:39:29 UTC
The fix has been already committed, so I am closing this PR.