1 /* Copyright (C) 1996, 2000 N.M. Maclaren
2 Copyright (C) 1996, 2000 The University of Cambridge
4 This includes all of the code needed to handle Berkeley sockets. It is way
5 outside current POSIX, unfortunately. It should be easy to convert to a system
6 that uses another mechanism. It does not currently use socklen_t, because
7 the only system that the author uses that has it is Linux. */
21 /* The code needs to set some variables during the open, for use by later
24 static int initial = 1,
25 descriptors[MAX_SOCKETS];
28 static struct sockaddr_storage here[MAX_SOCKETS], there[MAX_SOCKETS];
30 static struct sockaddr_in here[MAX_SOCKETS], there[MAX_SOCKETS];
34 /* There needs to be some disgusting grobble for handling timeouts, that is
35 identical to the grobble in internet.c. */
37 static jmp_buf jump_buffer;
39 static void jump_handler (int sig) {
40 longjmp(jump_buffer,1);
43 static void clear_alarm (void) {
49 if (signal(SIGALRM,SIG_DFL) == SIG_ERR)
50 fatal(1,"unable to reset signal handler",NULL);
56 void display_in_hex (const void *data, int length) {
59 for (i = 0; i < length; ++i)
60 fprintf(stderr,"%.2x",((const unsigned char *)data)[i]);
65 void display_sock_in_hex (struct sockaddr_storage *sock) {
67 struct sockaddr_in *sin;
68 struct sockaddr_in6 *sin6;
70 family = sock->ss_family;
73 sin = (struct sockaddr_in *)sock;
74 display_in_hex(&sin->sin_addr, sizeof(struct in_addr));
76 display_in_hex(&sin->sin_port, 2);
79 sin6 = (struct sockaddr_in6 *)sock;
80 display_in_hex(&sin6->sin6_addr, sizeof(struct in6_addr));
82 display_in_hex(&sin6->sin6_port, 2);
89 void display_sock_in_hex (struct sockaddr_in *sock) {
91 struct sockaddr_in *sin;
93 family = sock->sin_family;
96 sin = (struct sockaddr_in *)sock;
97 display_in_hex(&sin->sin_addr, sizeof(struct in_addr));
99 display_in_hex(&sin->sin_port, 2);
107 void open_socket (int which, char *hostname, int timespan) {
109 /* Locate the specified NTP server, set up a couple of addresses and open a
113 struct sockaddr_storage address, anywhere, everywhere;
115 /* Initialise and find out the server and port number. Note that the port
116 number is in network format. */
119 for (k = 0; k < MAX_SOCKETS; ++k)
122 if (which < 0 || which >= MAX_SOCKETS || descriptors[which] >= 0)
123 fatal(0,"socket index out of range or already open",NULL);
125 fprintf(stderr,"Looking for the socket addresses\n");
126 find_address(&address,&anywhere,&everywhere,&port,hostname,timespan);
128 fprintf(stderr,"Internet address: address=");
129 display_sock_in_hex(&address);
130 fprintf(stderr," anywhere=");
131 display_sock_in_hex(&anywhere);
132 fprintf(stderr," everywhere=");
133 display_sock_in_hex(&everywhere);
137 /* Set up our own and the target addresses. Note that the target address will
138 be reset before use in server mode. */
140 memset(&here[which], 0, sizeof(struct sockaddr_storage));
141 here[which] = anywhere;
142 if (!(operation == op_listen || operation == op_server))
143 ((struct sockaddr_in6 *)&here[which])->sin6_port = 0;
144 memset(&there[which], 0, sizeof(struct sockaddr_storage));
145 there[which] = (operation == op_broadcast ? everywhere : address);
147 fprintf(stderr,"Initial sockets: here=");
148 display_sock_in_hex(&here[which]);
149 fprintf(stderr," there=");
150 display_sock_in_hex(&there[which]);
154 /* Allocate a local UDP socket and configure it. */
156 switch(((struct sockaddr_in *)&there[which])->sin_family) {
158 sl = sizeof(struct sockaddr_in);
162 sl = sizeof(struct sockaddr_in6);
170 if ((descriptors[which] = socket(here[which].ss_family,SOCK_DGRAM,0)) < 0
171 || bind(descriptors[which],(struct sockaddr *)&here[which], sl) < 0)
172 fatal(1,"unable to allocate socket for NTP",NULL);
173 if (operation == op_broadcast) {
175 k = setsockopt(descriptors[which],SOL_SOCKET,SO_BROADCAST,
176 (void *)&k,sizeof(k));
177 if (k != 0) fatal(1,"unable to set permission to broadcast",NULL);
183 void open_socket (int which, char *hostname, int timespan) {
185 /* Locate the specified NTP server, set up a couple of addresses and open a
189 struct in_addr address, anywhere, everywhere;
191 /* Initialise and find out the server and port number. Note that the port
192 number is in network format. */
194 if (initial) for (k = 0; k < MAX_SOCKETS; ++k) descriptors[k] = -1;
196 if (which < 0 || which >= MAX_SOCKETS || descriptors[which] >= 0)
197 fatal(0,"socket index out of range or already open",NULL);
198 if (verbose > 2) fprintf(stderr,"Looking for the socket addresses\n");
199 find_address(&address,&anywhere,&everywhere,&port,hostname,timespan);
201 fprintf(stderr,"Internet address: address=");
202 display_in_hex(&address,sizeof(struct in_addr));
203 fprintf(stderr," anywhere=");
204 display_in_hex(&anywhere,sizeof(struct in_addr));
205 fprintf(stderr," everywhere=");
206 display_in_hex(&everywhere,sizeof(struct in_addr));
210 /* Set up our own and the target addresses. Note that the target address will
211 be reset before use in server mode. */
213 memset(&here[which],0,sizeof(struct sockaddr_in));
214 here[which].sin_family = AF_INET;
215 here[which].sin_port =
216 (operation == op_listen || operation == op_server ? port : 0);
217 here[which].sin_addr = anywhere;
218 memset(&there[which],0,sizeof(struct sockaddr_in));
219 there[which].sin_family = AF_INET;
220 there[which].sin_port = port;
221 there[which].sin_addr = (operation == op_broadcast ? everywhere : address);
223 fprintf(stderr,"Initial sockets: here=");
224 display_in_hex(&here[which].sin_addr,sizeof(struct in_addr));
226 display_in_hex(&here[which].sin_port,sizeof(here[which].sin_port));
227 fprintf(stderr," there=");
228 display_in_hex(&there[which].sin_addr,sizeof(struct in_addr));
230 display_in_hex(&there[which].sin_port,sizeof(there[which].sin_port));
234 /* Allocate a local UDP socket and configure it. */
237 if ((descriptors[which] = socket(AF_INET,SOCK_DGRAM,0)) < 0 ||
238 bind(descriptors[which],(struct sockaddr *)&here[which],
239 sizeof(here[which])) < 0)
240 fatal(1,"unable to allocate socket for NTP",NULL);
241 if (operation == op_broadcast) {
243 k = setsockopt(descriptors[which],SOL_SOCKET,SO_BROADCAST,
244 (void *)&k,sizeof(k));
245 if (k != 0) fatal(1,"unable to set permission to broadcast",NULL);
251 extern void write_socket (int which, void *packet, int length) {
253 /* Any errors in doing this are fatal - including blocking. Yes, this leaves a
254 server vulnerable to a denial of service attack. */
258 switch(((struct sockaddr_in *)&there[which])->sin_family) {
260 sl = sizeof(struct sockaddr_in);
264 sl = sizeof(struct sockaddr_in6);
271 if (which < 0 || which >= MAX_SOCKETS || descriptors[which] < 0)
272 fatal(0,"socket index out of range or not open",NULL);
274 k = sendto(descriptors[which],packet,(size_t)length,0,
275 (struct sockaddr *)&there[which],sl);
276 if (k != length) fatal(1,"unable to send NTP packet",NULL);
281 extern int read_socket (int which, void *packet, int length, int waiting) {
283 /* Read a packet and return its length or -1 for failure. Only incorrect
284 length and timeout are not fatal. */
287 struct sockaddr_storage scratch, *ptr;
289 struct sockaddr_in scratch, *ptr;
294 /* Under normal circumstances, set up a timeout. */
296 if (which < 0 || which >= MAX_SOCKETS || descriptors[which] < 0)
297 fatal(0,"socket index out of range or not open",NULL);
299 if (setjmp(jump_buffer)) {
301 fprintf(stderr,"Receive timed out\n");
302 else if (verbose > 1)
303 fprintf(stderr,"%s: receive timed out after %d seconds\n",
308 if (signal(SIGALRM,jump_handler) == SIG_ERR)
309 fatal(1,"unable to set up signal handler",NULL);
310 alarm((unsigned int)waiting);
313 /* Get the packet and clear the timeout, if any. */
315 if (operation == op_server)
316 memcpy(ptr = &there[which],&here[which],sizeof(scratch));
318 memcpy(ptr = &scratch,&there[which],sizeof(scratch));
321 k = recvfrom(descriptors[which],packet,(size_t)length,0,
322 (struct sockaddr *)ptr,&n);
323 if (waiting > 0) clear_alarm();
325 /* Now issue some low-level diagnostics. */
327 if (k <= 0) fatal(1,"unable to receive NTP packet from server",NULL);
329 fprintf(stderr,"Packet of length %d received from ",k);
330 display_sock_in_hex(ptr);
338 extern int flush_socket (int which) {
340 /* Get rid of any outstanding input, because it may have been hanging around
341 for a while. Ignore packet length oddities and return the number of packets
345 struct sockaddr_storage scratch;
347 struct sockaddr_in scratch;
351 int flags, count = 0, total = 0, k;
353 /* The code is the obvious. */
355 if (which < 0 || which >= MAX_SOCKETS || descriptors[which] < 0)
356 fatal(0,"socket index out of range or not open",NULL);
357 if (verbose > 2) fprintf(stderr,"Flushing outstanding packets\n");
359 if ((flags = fcntl(descriptors[which],F_GETFL,0)) < 0 ||
360 fcntl(descriptors[which],F_SETFL,flags|O_NONBLOCK) == -1)
361 fatal(1,"unable to set non-blocking mode",NULL);
365 k = recvfrom(descriptors[which],buffer,256,0,
366 (struct sockaddr *)&scratch,&n);
368 if (errno == EAGAIN || errno == EWOULDBLOCK) break;
369 fatal(1,"unable to flush socket",NULL);
375 if (fcntl(descriptors[which],F_SETFL,flags) == -1)
376 fatal(1,"unable to restore blocking mode",NULL);
378 fprintf(stderr,"Flushed %d packets totalling %d bytes\n",count,total);
384 extern void close_socket (int which) {
386 /* There is little point in shielding this with a timeout, because any hangs
387 are unlikely to be interruptible. It can get called when the sockets haven't
388 been opened, so ignore that case. */
390 if (which < 0 || which >= MAX_SOCKETS)
391 fatal(0,"socket index out of range",NULL);
392 if (descriptors[which] < 0) return;
394 if (close(descriptors[which])) fatal(1,"unable to close NTP socket",NULL);