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];
33
void display_in_hex(const void *, int);
35
void display_sock_in_hex(struct sockaddr_storage *);
37
void display_sock_in_hex (struct sockaddr_in *);
40
/* There needs to be some disgusting grobble for handling timeouts, that is
41
identical to the grobble in internet.c. */
43
static jmp_buf jump_buffer;
45
static void jump_handler (int sig) {
46
longjmp(jump_buffer,1);
49
static void clear_alarm (void) {
55
if (signal(SIGALRM,SIG_DFL) == SIG_ERR)
56
fatal(1,"unable to reset signal handler",NULL);
62
void display_in_hex (const void *data, int length) {
65
for (i = 0; i < length; ++i)
66
fprintf(stderr,"%.2x",((const unsigned char *)data)[i]);
71
void display_sock_in_hex (struct sockaddr_storage *sock) {
73
struct sockaddr_in *sin;
74
struct sockaddr_in6 *sin6;
76
family = sock->ss_family;
79
sin = (struct sockaddr_in *)sock;
80
display_in_hex(&sin->sin_addr, sizeof(struct in_addr));
82
display_in_hex(&sin->sin_port, 2);
85
sin6 = (struct sockaddr_in6 *)sock;
86
display_in_hex(&sin6->sin6_addr, sizeof(struct in6_addr));
88
display_in_hex(&sin6->sin6_port, 2);
95
void display_sock_in_hex (struct sockaddr_in *sock) {
97
struct sockaddr_in *sin;
99
family = sock->sin_family;
102
sin = (struct sockaddr_in *)sock;
103
display_in_hex(&sin->sin_addr, sizeof(struct in_addr));
105
display_in_hex(&sin->sin_port, 2);
113
void open_socket (int which, char *hostname, int timespan) {
115
/* Locate the specified NTP server, set up a couple of addresses and open a
119
struct sockaddr_storage address, anywhere, everywhere;
121
/* Initialise and find out the server and port number. Note that the port
122
number is in network format. */
125
for (k = 0; k < MAX_SOCKETS; ++k)
128
if (which < 0 || which >= MAX_SOCKETS || descriptors[which] >= 0)
129
fatal(0,"socket index out of range or already open",NULL);
131
fprintf(stderr,"Looking for the socket addresses\n");
132
find_address(&address,&anywhere,&everywhere,&port,hostname,timespan);
134
fprintf(stderr,"Internet address: address=");
135
display_sock_in_hex(&address);
136
fprintf(stderr," anywhere=");
137
display_sock_in_hex(&anywhere);
138
fprintf(stderr," everywhere=");
139
display_sock_in_hex(&everywhere);
143
/* Set up our own and the target addresses. Note that the target address will
144
be reset before use in server mode. */
146
memset(&here[which], 0, sizeof(struct sockaddr_storage));
147
here[which] = anywhere;
148
if (!(operation == op_listen || operation == op_server))
149
((struct sockaddr_in6 *)&here[which])->sin6_port = 0;
150
memset(&there[which], 0, sizeof(struct sockaddr_storage));
151
there[which] = (operation == op_broadcast ? everywhere : address);
153
fprintf(stderr,"Initial sockets: here=");
154
display_sock_in_hex(&here[which]);
155
fprintf(stderr," there=");
156
display_sock_in_hex(&there[which]);
160
/* Allocate a local UDP socket and configure it. */
162
switch(((struct sockaddr_in *)&there[which])->sin_family) {
164
sl = sizeof(struct sockaddr_in);
168
sl = sizeof(struct sockaddr_in6);
176
if ((descriptors[which] = socket(here[which].ss_family,SOCK_DGRAM,0)) < 0
177
|| bind(descriptors[which],(struct sockaddr *)&here[which], sl) < 0)
178
fatal(1,"unable to allocate socket for NTP",NULL);
179
if (operation == op_broadcast) {
181
k = setsockopt(descriptors[which],SOL_SOCKET,SO_BROADCAST,
182
(void *)&k,sizeof(k));
183
if (k != 0) fatal(1,"unable to set permission to broadcast",NULL);
189
void open_socket (int which, char *hostname, int timespan) {
191
/* Locate the specified NTP server, set up a couple of addresses and open a
195
struct in_addr address, anywhere, everywhere;
197
/* Initialise and find out the server and port number. Note that the port
198
number is in network format. */
200
if (initial) for (k = 0; k < MAX_SOCKETS; ++k) descriptors[k] = -1;
202
if (which < 0 || which >= MAX_SOCKETS || descriptors[which] >= 0)
203
fatal(0,"socket index out of range or already open",NULL);
204
if (verbose > 2) fprintf(stderr,"Looking for the socket addresses\n");
205
find_address(&address,&anywhere,&everywhere,&port,hostname,timespan);
207
fprintf(stderr,"Internet address: address=");
208
display_in_hex(&address,sizeof(struct in_addr));
209
fprintf(stderr," anywhere=");
210
display_in_hex(&anywhere,sizeof(struct in_addr));
211
fprintf(stderr," everywhere=");
212
display_in_hex(&everywhere,sizeof(struct in_addr));
216
/* Set up our own and the target addresses. Note that the target address will
217
be reset before use in server mode. */
219
memset(&here[which],0,sizeof(struct sockaddr_in));
220
here[which].sin_family = AF_INET;
221
here[which].sin_port =
222
(operation == op_listen || operation == op_server ? port : 0);
223
here[which].sin_addr = anywhere;
224
memset(&there[which],0,sizeof(struct sockaddr_in));
225
there[which].sin_family = AF_INET;
226
there[which].sin_port = port;
227
there[which].sin_addr = (operation == op_broadcast ? everywhere : address);
229
fprintf(stderr,"Initial sockets: here=");
230
display_in_hex(&here[which].sin_addr,sizeof(struct in_addr));
232
display_in_hex(&here[which].sin_port,sizeof(here[which].sin_port));
233
fprintf(stderr," there=");
234
display_in_hex(&there[which].sin_addr,sizeof(struct in_addr));
236
display_in_hex(&there[which].sin_port,sizeof(there[which].sin_port));
240
/* Allocate a local UDP socket and configure it. */
243
if ((descriptors[which] = socket(AF_INET,SOCK_DGRAM,0)) < 0 ||
244
bind(descriptors[which],(struct sockaddr *)&here[which],
245
sizeof(here[which])) < 0)
246
fatal(1,"unable to allocate socket for NTP",NULL);
247
if (operation == op_broadcast) {
249
k = setsockopt(descriptors[which],SOL_SOCKET,SO_BROADCAST,
250
(void *)&k,sizeof(k));
251
if (k != 0) fatal(1,"unable to set permission to broadcast",NULL);
257
extern void write_socket (int which, void *packet, int length) {
259
/* Any errors in doing this are fatal - including blocking. Yes, this leaves a
260
server vulnerable to a denial of service attack. */
264
switch(((struct sockaddr_in *)&there[which])->sin_family) {
266
sl = sizeof(struct sockaddr_in);
270
sl = sizeof(struct sockaddr_in6);
277
if (which < 0 || which >= MAX_SOCKETS || descriptors[which] < 0)
278
fatal(0,"socket index out of range or not open",NULL);
280
k = sendto(descriptors[which],packet,(size_t)length,0,
281
(struct sockaddr *)&there[which],sl);
282
if (k != length) fatal(1,"unable to send NTP packet",NULL);
287
extern int read_socket (int which, void *packet, int length, int waiting) {
289
/* Read a packet and return its length or -1 for failure. Only incorrect
290
length and timeout are not fatal. */
293
struct sockaddr_storage scratch, *ptr;
295
struct sockaddr_in scratch, *ptr;
300
/* Under normal circumstances, set up a timeout. */
302
if (which < 0 || which >= MAX_SOCKETS || descriptors[which] < 0)
303
fatal(0,"socket index out of range or not open",NULL);
305
if (setjmp(jump_buffer)) {
307
fprintf(stderr,"Receive timed out\n");
308
else if (verbose > 1)
309
fprintf(stderr,"%s: receive timed out after %d seconds\n",
314
if (signal(SIGALRM,jump_handler) == SIG_ERR)
315
fatal(1,"unable to set up signal handler",NULL);
316
alarm((unsigned int)waiting);
319
/* Get the packet and clear the timeout, if any. */
321
if (operation == op_server)
322
memcpy(ptr = &there[which],&here[which],sizeof(scratch));
324
memcpy(ptr = &scratch,&there[which],sizeof(scratch));
327
k = recvfrom(descriptors[which],packet,(size_t)length,0,
328
(struct sockaddr *)ptr,&n);
329
if (waiting > 0) clear_alarm();
331
/* Now issue some low-level diagnostics. */
333
if (k <= 0) fatal(1,"unable to receive NTP packet from server",NULL);
335
fprintf(stderr,"Packet of length %d received from ",k);
336
display_sock_in_hex(ptr);
344
extern int flush_socket (int which) {
346
/* Get rid of any outstanding input, because it may have been hanging around
347
for a while. Ignore packet length oddities and return the number of packets
351
struct sockaddr_storage scratch;
353
struct sockaddr_in scratch;
357
int flags, count = 0, total = 0, k;
359
/* The code is the obvious. */
361
if (which < 0 || which >= MAX_SOCKETS || descriptors[which] < 0)
362
fatal(0,"socket index out of range or not open",NULL);
363
if (verbose > 2) fprintf(stderr,"Flushing outstanding packets\n");
365
if ((flags = fcntl(descriptors[which],F_GETFL,0)) < 0 ||
366
fcntl(descriptors[which],F_SETFL,flags|O_NONBLOCK) == -1)
367
fatal(1,"unable to set non-blocking mode",NULL);
371
k = recvfrom(descriptors[which],buffer,256,0,
372
(struct sockaddr *)&scratch,&n);
374
if (errno == EAGAIN || errno == EWOULDBLOCK) break;
375
fatal(1,"unable to flush socket",NULL);
381
if (fcntl(descriptors[which],F_SETFL,flags) == -1)
382
fatal(1,"unable to restore blocking mode",NULL);
384
fprintf(stderr,"Flushed %d packets totalling %d bytes\n",count,total);
390
extern void close_socket (int which) {
392
/* There is little point in shielding this with a timeout, because any hangs
393
are unlikely to be interruptible. It can get called when the sockets haven't
394
been opened, so ignore that case. */
396
if (which < 0 || which >= MAX_SOCKETS)
397
fatal(0,"socket index out of range",NULL);
398
if (descriptors[which] < 0) return;
400
if (close(descriptors[which])) fatal(1,"unable to close NTP socket",NULL);