1 /* $OpenBSD: src/usr.sbin/ntpd/server.c,v 1.21 2005/01/28 12:01:32 dtucker Exp $ */
4 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5 * Copyright (c) 2004 Alexander Guy <alexander@openbsd.org>
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
16 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
17 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include <sys/types.h>
21 #include <sys/socket.h>
32 setup_listeners(struct servent
*se
, struct ntpd_conf
*conf
, u_int
*cnt
)
34 struct listen_addr
*la
;
35 struct ifaddrs
*ifa
, *ifap
;
38 int tos
= IPTOS_LOWDELAY
;
40 if (conf
->listen_all
) {
41 if (getifaddrs(&ifa
) == -1)
44 for (ifap
= ifa
; ifap
!= NULL
; ifap
= ifap
->ifa_next
) {
47 if (sa
->sa_family
!= AF_INET
&&
48 sa
->sa_family
!= AF_INET6
)
51 if ((la
= calloc(1, sizeof(struct listen_addr
))) ==
53 fatal("setup_listeners calloc");
55 memcpy(&la
->sa
, sa
, SA_LEN(sa
));
56 TAILQ_INSERT_TAIL(&conf
->listen_addrs
, la
, entry
);
62 TAILQ_FOREACH(la
, &conf
->listen_addrs
, entry
) {
65 switch (la
->sa
.ss_family
) {
67 if (((struct sockaddr_in
*)&la
->sa
)->sin_port
== 0)
68 ((struct sockaddr_in
*)&la
->sa
)->sin_port
=
72 if (((struct sockaddr_in6
*)&la
->sa
)->sin6_port
== 0)
73 ((struct sockaddr_in6
*)&la
->sa
)->sin6_port
=
77 fatalx("king bula sez: af borked");
80 log_info("listening on %s",
81 log_sockaddr((struct sockaddr
*)&la
->sa
));
83 if ((la
->fd
= socket(la
->sa
.ss_family
, SOCK_DGRAM
, 0)) == -1)
86 if (la
->sa
.ss_family
== AF_INET
&& setsockopt(la
->fd
,
87 IPPROTO_IP
, IP_TOS
, &tos
, sizeof(tos
)) == -1)
88 log_warn("setsockopt IPTOS_LOWDELAY");
90 if (bind(la
->fd
, (struct sockaddr
*)&la
->sa
,
91 SA_LEN((struct sockaddr
*)&la
->sa
)) == -1)
101 server_dispatch(int fd
, struct ntpd_conf
*conf
)
106 struct sockaddr_storage fsa
;
108 struct ntp_msg query
, reply
;
109 char buf
[NTP_MSGSIZE
];
111 fsa_len
= sizeof(fsa
);
112 if ((size
= recvfrom(fd
, &buf
, sizeof(buf
), 0,
113 (struct sockaddr
*)&fsa
, &fsa_len
)) == -1) {
114 if (errno
== EHOSTUNREACH
|| errno
== EHOSTDOWN
||
115 errno
== ENETUNREACH
|| errno
== ENETDOWN
) {
116 log_warn("recvfrom %s",
117 log_sockaddr((struct sockaddr
*)&fsa
));
125 if (ntp_getmsg(buf
, size
, &query
) == -1)
128 version
= (query
.status
& VERSIONMASK
) >> 3;
130 bzero(&reply
, sizeof(reply
));
131 reply
.status
= conf
->status
.leap
| (query
.status
& VERSIONMASK
);
132 if ((query
.status
& MODEMASK
) == MODE_CLIENT
)
133 reply
.status
|= MODE_SERVER
;
135 reply
.status
|= MODE_SYM_PAS
;
137 reply
.stratum
= conf
->status
.stratum
;
138 reply
.ppoll
= query
.ppoll
;
139 reply
.precision
= conf
->status
.precision
;
140 reply
.rectime
= d_to_lfp(rectime
);
141 reply
.reftime
= d_to_lfp(conf
->status
.reftime
);
142 reply
.xmttime
= d_to_lfp(gettime());
143 reply
.orgtime
= query
.xmttime
;
144 reply
.rootdelay
= d_to_sfp(conf
->status
.rootdelay
);
147 reply
.refid
= reply
.xmttime
.fractionl
;
149 reply
.refid
= conf
->status
.refid
;
151 ntp_sendmsg(fd
, (struct sockaddr
*)&fsa
, &reply
, size
, 0);