xref: /freebsd/contrib/ntp/libntp/numtoa.c (revision f5f40dd6)
1 /*
2  * numtoa - return asciized network numbers store in local array space
3  */
4 #include <config.h>
5 
6 #include <sys/types.h>
7 #ifdef HAVE_NETINET_IN_H
8 #include <netinet/in.h>		/* ntohl */
9 #endif
10 
11 #include <stdio.h>
12 #include <ctype.h>
13 
14 #include "ntp_fp.h"
15 #include "ntp_stdlib.h"
16 
17 char *
numtoa(u_int32 num)18 numtoa(
19 	u_int32 num
20 	)
21 {
22 	register u_int32 netnum;
23 	register char *buf;
24 
25 	netnum = ntohl(num);
26 	LIB_GETBUF(buf);
27 	snprintf(buf, LIB_BUFLENGTH, "%lu.%lu.%lu.%lu",
28 		 ((u_long)netnum >> 24) & 0xff,
29 		 ((u_long)netnum >> 16) & 0xff,
30 		 ((u_long)netnum >> 8) & 0xff,
31 		 (u_long)netnum & 0xff);
32 	return buf;
33 }
34 
35 
36 /*
37  * Convert a refid & stratum to a string.  If stratum is negative and the
38  * refid consists entirely of graphic chars, up to an optional
39  * terminating zero, display as text similar to stratum 0 & 1.
40  */
41 const char *
refid_str(u_int32 refid,int stratum)42 refid_str(
43 	u_int32	refid,
44 	int	stratum
45 	)
46 {
47 	char *	text;
48 	size_t	tlen;
49 	char *	cp;
50 	int	printable;
51 
52 	/*
53 	 * ntpd can have stratum = 0 and refid 127.0.0.1 in orphan mode.
54 	 * https://bugs.ntp.org/3854.  Mirror the refid logic in timer().
55 	 */
56 	if (0 == stratum && LOOPBACKADR_N == refid) {
57 		return ".ORPH.";
58 	}
59 	printable = FALSE;
60 	if (stratum < 2) {
61 		text = lib_getbuf();
62 		text[0] = '.';
63 		memcpy(&text[1], &refid, sizeof(refid));
64 		text[1 + sizeof(refid)] = '\0';
65 		tlen = strlen(text);
66 		text[tlen] = '.';
67 		text[tlen + 1] = '\0';
68 		/*
69 		 * Now make sure the contents are 'graphic'.
70 		 *
71 		 * This refid is expected to be up to 4 printable ASCII.
72 		 * isgraph() is similar to isprint() but excludes space.
73 		 * If any character is not graphic, replace it with a '?'.
74 		 * This will at least alert the viewer of a problem.
75 		 */
76 		for (cp = text + 1; '\0' != *cp; ++cp) {
77 			if (!isgraph((int)*cp)) {
78 				printable = FALSE;
79 				*cp = '?';
80 			}
81 		}
82 		if (   (stratum < 0 && printable)
83 		    || stratum < 2) {
84 			return text;
85 		}
86 	}
87 	return numtoa(refid);
88 }
89 
90