[ntp:questions] Re: Can sync via IPv4 but not IPv6?

Ronan Flood ronan at noc.ulcc.ac.uk
Thu Mar 3 14:12:10 UTC 2005


dan at ingeni.us (Dan Lowe) wrote:

> I have a number of hosts from which I provide time service to customers.
> These hosts all work perfectly fine via the IPv4 layer.  I am seeing
> behavior on the IPv6 layer that I can't explain...
> 
> The IP addresses and such below are real - I invite anybody to test against

Thanks.  Having done some debugging, I have a conclusion.

> them, if you think it will be of use.  Obviously, attacks are not welcome
> and will be referred to my security and legal departments. 
> 
> 
> Some pertinent information about the server host shown below...
> 
> SunOS 5.8 (Solaris 8) Generic_108528-18
> Sun UltraSPARC Netra (SUNW,UltraSPARC-IIi-cEngine)
> Running NTP daemon version 4.2.0 (release)
> 
> 
> Here's the error I get from the client.

Is the client also running Solaris, or what?

> # bin/ntpdate -6 2001:418:0:7000::53
> Looking for host 2001:418:0:7000::53 and service ntp
> host found : resolv1.nycmny01.us.to.verio.net
> 26 Feb 00:34:44 ntpdate[8801]: no server suitable for synchronization found

Running ntpdate -d would have given you a bit more info, but not enough
to help, I suspect.

Anyway this looks like a bug in ntpdate, routine findserver().
It does a memcmp against a full socket structure, which at this
point, on my Solaris host anyway, is effectively a struct sockaddr_in6,
and the two differ in the last byte, which is part of what netinet/in.h
identifies as

          uint32_t        __sin6_src_id;  /* Impl. specific - UDP replies */

I added debugging code to findserver() just before the memcmp :
                
                if (debug) {
                        unsigned char *p1 = (unsigned char *)addr;
                        unsigned char *p2 = (unsigned char *) (&server->srcadr);
                        int j;

                        printf("findserver comparing %s %s %d\n",
                                stoa(addr), stoa(&server->srcadr),
                                SOCKLEN(addr));
                        for (j = 0; j < SOCKLEN(addr); j++, p1++, p2++)
                                printf("byte %2d: %2x %2x\n", j,
                                        (unsigned int) *p1,
                                        (unsigned int) *p2);
                }

which produced this (compressed here)

findserver comparing 2001:418:0:7000::53 2001:418:0:7000::53 32
byte  0:  0  0 byte  1: 1a 1a byte  2:  0  0 byte  3: 7b 7b
byte  4:  0  0 byte  5:  0  0 byte  6:  0  0 byte  7:  0  0
byte  8: 20 20 byte  9:  1  1 byte 10:  4  4 byte 11: 18 18
byte 12:  0  0 byte 13:  0  0 byte 14: 70 70 byte 15:  0  0
byte 16:  0  0 byte 17:  0  0 byte 18:  0  0 byte 19:  0  0
byte 20:  0  0 byte 21:  0  0 byte 22:  0  0 byte 23: 53 53
byte 24:  0  0 byte 25:  0  0 byte 26:  0  0 byte 27:  0  0
byte 28:  0  0 byte 29:  0  0 byte 30:  0  0 byte 31:  6  0  <===

-- 
                      Ronan Flood <R.Flood at noc.ulcc.ac.uk>
                        working for but not speaking for
             Network Services, University of London Computer Centre
     (which means: don't bother ULCC if I've said something you don't like)



More information about the questions mailing list