Code

chrony: fix type instances for reference clocks
authorMiroslav Lichvar <mlichvar@redhat.com>
Thu, 23 Feb 2017 14:28:19 +0000 (15:28 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 23 Feb 2017 16:48:58 +0000 (17:48 +0100)
When chronyd is using a reference clock, the reference ID of the source
is provided as an IPv4 address in the source report. Format it as an
ASCII string instead of an IPv4 address.

src/chrony.c

index bad9cb78891c46073aaf5a400b25f95bb4bd958b..835c42538d1f3b46a41952368b380108744ca138 100644 (file)
@@ -77,6 +77,7 @@ static uint32_t g_chrony_seq_is_initialized;
 #define IPADDR_INET4 1
 #define IPADDR_INET6 2
 #define IPV6_STR_MAX_SIZE (8 * 4 + 7 + 1)
+#define MODE_REFCLOCK 2
 
 typedef enum { PKT_TYPE_CMD_REQUEST = 1, PKT_TYPE_CMD_REPLY = 2 } ePacketType;
 
@@ -354,6 +355,19 @@ static char *niptoha(const tChrony_IPAddr *addr, char *p_buf,
   return p_buf;
 }
 
+static void nreftostr(uint32_t nrefid, char *p_buf, size_t p_buf_size) {
+  int i, j, c;
+
+  for (i = j = 0; i < 4; i++) {
+    c = ntohl(nrefid) << i * 8 >> 24;
+    if (!isalnum(c) || j + 1 >= p_buf_size)
+      continue;
+    p_buf[j++] = c;
+  }
+  if (j < p_buf_size)
+    p_buf[j] = '\0';
+}
+
 static int chrony_set_timeout(void) {
   /* Set the socket's  timeout to g_chrony_timeout; a value of 0 signals
    * infinite timeout */
@@ -851,7 +865,11 @@ static int chrony_request_source_data(int p_src_idx, char *src_addr,
     return rc;
   }
 
-  niptoha(&chrony_resp.body.source_data.addr, src_addr, addr_size);
+  if (ntohs(chrony_resp.body.source_data.f_mode) == MODE_REFCLOCK)
+    nreftostr(chrony_resp.body.source_data.addr.addr.ip4, src_addr, addr_size);
+  else
+    niptoha(&chrony_resp.body.source_data.addr, src_addr, addr_size);
+
   DEBUG(PLUGIN_NAME ": Source[%d] data: .addr = %s, .poll = %u, .stratum = %u, "
                     ".state = %u, .mode = %u, .flags = %u, .reach = %u, "
                     ".latest_meas_ago = %u, .orig_latest_meas = %f, "