1 /*	$OpenBSD: ntp_msg.c,v 1.15 2005/09/24 00:32:03 dtucker Exp $ */
2 
3 /*
4  * Copyright © 2013
5  *	Thorsten “mirabilos” Glaser <tg@mirbsd.org>
6  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
7  * Copyright (c) 2004 Alexander Guy <alexander.guy@andern.org>
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
18  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
19  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  */
21 
22 #include <sys/param.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <errno.h>
27 
28 #include "ntpd.h"
29 #include "ntp.h"
30 
31 __RCSID("$MirOS: src/usr.sbin/ntpd/ntp_msg.c,v 1.5 2013/10/31 20:07:28 tg Exp $");
32 
33 int
ntp_getmsg(struct sockaddr * sa,char * p,ssize_t len,struct ntp_msg * msg)34 ntp_getmsg(struct sockaddr *sa, char *p, ssize_t len, struct ntp_msg *msg)
35 {
36 	if (len != NTP_MSGSIZE_NOAUTH && len != NTP_MSGSIZE) {
37 		log_warnx("malformed packet received from %s",
38 		    log_sockaddr(sa));
39 		return (-1);
40 	}
41 
42 #define	copyin(f,p)	memcpy(&(f), (p), sizeof(f)); (p) += sizeof(f)
43 
44 	copyin(msg->status, p);
45 	copyin(msg->stratum, p);
46 	copyin(msg->ppoll, p);
47 	copyin(msg->precision, p);
48 	copyin(msg->rootdelay.int_parts, p);
49 	copyin(msg->rootdelay.fractions, p);
50 	copyin(msg->dispersion.int_parts, p);
51 	copyin(msg->dispersion.fractions, p);
52 	copyin(msg->refid, p);
53 	copyin(msg->reftime.int_partl, p);
54 	copyin(msg->reftime.fractionl, p);
55 	copyin(msg->orgtime.int_partl, p);
56 	copyin(msg->orgtime.fractionl, p);
57 	copyin(msg->rectime.int_partl, p);
58 	copyin(msg->rectime.fractionl, p);
59 	copyin(msg->xmttime.int_partl, p);
60 	copyin(msg->xmttime.fractionl, p);
61 
62 	return (0);
63 }
64 
65 int
ntp_sendmsg(int fd,struct sockaddr * sa,struct ntp_msg * msg,ssize_t len,int auth)66 ntp_sendmsg(int fd, struct sockaddr *sa, struct ntp_msg *msg, ssize_t len,
67     int auth __attribute__((__unused__)))
68 {
69 	char		 buf[NTP_MSGSIZE];
70 	char		*p = buf;
71 	socklen_t	sa_len;
72 
73 #define	copyout(p,f)	memcpy((p), &(f), sizeof(f)); p += sizeof(f)
74 
75 	copyout(p, msg->status);
76 	copyout(p, msg->stratum);
77 	copyout(p, msg->ppoll);
78 	copyout(p, msg->precision);
79 	copyout(p, msg->rootdelay.int_parts);
80 	copyout(p, msg->rootdelay.fractions);
81 	copyout(p, msg->dispersion.int_parts);
82 	copyout(p, msg->dispersion.fractions);
83 	copyout(p, msg->refid);
84 	copyout(p, msg->reftime.int_partl);
85 	copyout(p, msg->reftime.fractionl);
86 	copyout(p, msg->orgtime.int_partl);
87 	copyout(p, msg->orgtime.fractionl);
88 	copyout(p, msg->rectime.int_partl);
89 	copyout(p, msg->rectime.fractionl);
90 	copyout(p, msg->xmttime.int_partl);
91 	copyout(p, msg->xmttime.fractionl);
92 
93 	if (sa != NULL)
94 		sa_len = SA_LEN(sa);
95 	else
96 		sa_len = 0;
97 
98 	if (sendto(fd, &buf, len, 0, sa, sa_len) != len) {
99 		if (errno == ENOBUFS || errno == EHOSTUNREACH ||
100 		    errno == ENETDOWN || errno == EHOSTDOWN) {
101 			/* logging is futile */
102 			return (-1);
103 		}
104 		log_warn("sendto");
105 		if (errno == EINVAL)
106 			return (-2);
107 		return (-1);
108 	}
109 
110 	return (0);
111 }
112