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