Commit | Line | Data |
---|---|---|
059ec3d9 PH |
1 | /************************************************* |
2 | * Exim - an Internet mail transport agent * | |
3 | *************************************************/ | |
4 | ||
c4ceed07 | 5 | /* Copyright (c) University of Cambridge 1995 - 2012 */ |
059ec3d9 PH |
6 | /* See the file NOTICE for conditions of use and distribution. */ |
7 | ||
8 | #ifdef STAND_ALONE | |
9 | #include <signal.h> | |
10 | #include <stdio.h> | |
11 | #include <time.h> | |
12 | #endif | |
13 | ||
14 | /* This source file contains "default" system-dependent functions which | |
15 | provide functionality (or lack of it) in cases where the OS-specific os.c | |
16 | file has not. Some of them are tailored by macros defined in os.h files. */ | |
17 | ||
18 | ||
19 | #ifndef OS_RESTARTING_SIGNAL | |
20 | /************************************************* | |
21 | * Set up restarting signal * | |
22 | *************************************************/ | |
23 | ||
24 | /* This function has the same functionality as the ANSI C signal() function, | |
25 | except that it arranges that, if the signal happens during a system call, the | |
26 | system call gets restarted. (Also, it doesn't return a result.) Different | |
27 | versions of Unix have different defaults, and different ways of setting up a | |
28 | restarting signal handler. If the functionality is not available, the signal | |
29 | should be set to be ignored. This function is used only for catching SIGUSR1. | |
30 | */ | |
31 | ||
32 | void | |
33 | os_restarting_signal(int sig, void (*handler)(int)) | |
34 | { | |
35 | /* Many systems have the SA_RESTART sigaction for specifying that a signal | |
36 | should restart system calls. These include SunOS5, AIX, BSDI, IRIX, FreeBSD, | |
37 | OSF1, Linux and HP-UX 10 (but *not* HP-UX 9). */ | |
38 | ||
39 | #ifdef SA_RESTART | |
40 | struct sigaction act; | |
41 | act.sa_handler = handler; | |
42 | sigemptyset(&(act.sa_mask)); | |
43 | act.sa_flags = SA_RESTART; | |
44 | sigaction(sig, &act, NULL); | |
45 | ||
46 | #ifdef STAND_ALONE | |
47 | printf("Used SA_RESTART\n"); | |
48 | #endif | |
49 | ||
50 | /* SunOS4 and Ultrix default to non-interruptable signals, with SV_INTERRUPT | |
51 | for making them interruptable. This seems to be a dying fashion. */ | |
52 | ||
53 | #elif defined SV_INTERRUPT | |
54 | signal(sig, handler); | |
55 | ||
56 | #ifdef STAND_ALONE | |
57 | printf("Used default signal()\n"); | |
58 | #endif | |
59 | ||
60 | ||
61 | /* If neither SA_RESTART nor SV_INTERRUPT is available we don't know how to | |
62 | set up a restarting signal, so simply suppress the facility. */ | |
63 | ||
64 | #else | |
65 | signal(sig, SIG_IGN); | |
66 | ||
67 | #ifdef STAND_ALONE | |
68 | printf("Used SIG_IGN\n"); | |
69 | #endif | |
70 | ||
71 | #endif | |
72 | } | |
73 | ||
74 | #endif /* OS_RESTARTING_SIGNAL */ | |
75 | ||
76 | ||
77 | #ifndef OS_NON_RESTARTING_SIGNAL | |
78 | /************************************************* | |
79 | * Set up non-restarting signal * | |
80 | *************************************************/ | |
81 | ||
82 | /* This function has the same functionality as the ANSI C signal() function, | |
83 | except that it arranges that, if the signal happens during a system call, the | |
84 | system call gets interrupted. (Also, it doesn't return a result.) Different | |
85 | versions of Unix have different defaults, and different ways of setting up a | |
86 | non-restarting signal handler. For systems for which we don't know what to do, | |
87 | just use the normal signal() function and hope for the best. */ | |
88 | ||
89 | void | |
90 | os_non_restarting_signal(int sig, void (*handler)(int)) | |
91 | { | |
92 | /* Many systems have the SA_RESTART sigaction for specifying that a signal | |
93 | should restart system calls. These include SunOS5, AIX, BSDI, IRIX, FreeBSD, | |
94 | OSF1, Linux and HP-UX 10 (but *not* HP-UX 9). */ | |
95 | ||
96 | #ifdef SA_RESTART | |
97 | struct sigaction act; | |
98 | act.sa_handler = handler; | |
99 | sigemptyset(&(act.sa_mask)); | |
100 | act.sa_flags = 0; | |
101 | sigaction(sig, &act, NULL); | |
102 | ||
103 | #ifdef STAND_ALONE | |
104 | printf("Used sigaction() with flags = 0\n"); | |
105 | #endif | |
106 | ||
107 | /* SunOS4 and Ultrix default to non-interruptable signals, with SV_INTERRUPT | |
108 | for making them interruptable. This seems to be a dying fashion. */ | |
109 | ||
110 | #elif defined SV_INTERRUPT | |
111 | struct sigvec sv; | |
112 | sv.sv_handler = handler; | |
113 | sv.sv_flags = SV_INTERRUPT; | |
114 | sv.sv_mask = -1; | |
115 | sigvec(sig, &sv, NULL); | |
116 | ||
117 | #ifdef STAND_ALONE | |
118 | printf("Used sigvec() with flags = SV_INTERRUPT\n"); | |
119 | #endif | |
120 | ||
121 | /* If neither SA_RESTART nor SV_INTERRUPT is available we don't know how to | |
122 | set up a restarting signal, so just use the standard signal() function. */ | |
123 | ||
124 | #else | |
125 | signal(sig, handler); | |
126 | ||
127 | #ifdef STAND_ALONE | |
128 | printf("Used default signal()\n"); | |
129 | #endif | |
130 | ||
131 | #endif | |
132 | } | |
133 | ||
134 | #endif /* OS_NON_RESTARTING_SIGNAL */ | |
135 | ||
136 | ||
137 | ||
138 | #ifdef STRERROR_FROM_ERRLIST | |
139 | /************************************************* | |
140 | * Provide strerror() for non-ANSI libraries * | |
141 | *************************************************/ | |
142 | ||
143 | /* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror() | |
144 | in their libraries, but can provide the same facility by this simple | |
145 | alternative function. */ | |
146 | ||
147 | char * | |
148 | strerror(int n) | |
149 | { | |
150 | if (n < 0 || n >= sys_nerr) return "unknown error number"; | |
151 | return sys_errlist[n]; | |
152 | } | |
153 | #endif /* STRERROR_FROM_ERRLIST */ | |
154 | ||
155 | ||
156 | ||
157 | #ifndef OS_STRSIGNAL | |
158 | /************************************************* | |
159 | * Provide strsignal() for systems without * | |
160 | *************************************************/ | |
161 | ||
162 | /* Some systems have strsignal() to turn signal numbers into names; others | |
163 | may have other means of doing this. This function is used for those systems | |
164 | that have nothing. It provides a basic translation for the common standard | |
165 | signal numbers. I've been extra cautious with the ifdef's here. Probably more | |
166 | than is necessary... */ | |
167 | ||
1ba28e2b PP |
168 | const char * |
169 | os_strsignal(const int n) | |
059ec3d9 PH |
170 | { |
171 | switch (n) | |
172 | { | |
173 | #ifdef SIGHUP | |
174 | case SIGHUP: return "hangup"; | |
175 | #endif | |
176 | ||
177 | #ifdef SIGINT | |
178 | case SIGINT: return "interrupt"; | |
179 | #endif | |
180 | ||
181 | #ifdef SIGQUIT | |
182 | case SIGQUIT: return "quit"; | |
183 | #endif | |
184 | ||
185 | #ifdef SIGILL | |
186 | case SIGILL: return "illegal instruction"; | |
187 | #endif | |
188 | ||
189 | #ifdef SIGTRAP | |
190 | case SIGTRAP: return "trace trap"; | |
191 | #endif | |
192 | ||
193 | #ifdef SIGABRT | |
194 | case SIGABRT: return "abort"; | |
195 | #endif | |
196 | ||
197 | #ifdef SIGEMT | |
198 | case SIGEMT: return "EMT instruction"; | |
199 | #endif | |
200 | ||
201 | #ifdef SIGFPE | |
202 | case SIGFPE: return "arithmetic exception"; | |
203 | #endif | |
204 | ||
205 | #ifdef SIGKILL | |
206 | case SIGKILL: return "killed"; | |
207 | #endif | |
208 | ||
209 | #ifdef SIGBUS | |
210 | case SIGBUS: return "bus error"; | |
211 | #endif | |
212 | ||
213 | #ifdef SIGSEGV | |
214 | case SIGSEGV: return "segmentation fault"; | |
215 | #endif | |
216 | ||
217 | #ifdef SIGSYS | |
218 | case SIGSYS: return "bad system call"; | |
219 | #endif | |
220 | ||
221 | #ifdef SIGPIPE | |
222 | case SIGPIPE: return "broken pipe"; | |
223 | #endif | |
224 | ||
225 | #ifdef SIGALRM | |
226 | case SIGALRM: return "alarm"; | |
227 | #endif | |
228 | ||
229 | #ifdef SIGTERM | |
230 | case SIGTERM: return "terminated"; | |
231 | #endif | |
232 | ||
233 | #ifdef SIGUSR1 | |
234 | case SIGUSR1: return "user signal 1"; | |
235 | #endif | |
236 | ||
237 | #ifdef SIGUSR2 | |
238 | case SIGUSR2: return "user signal 2"; | |
239 | #endif | |
240 | ||
241 | #ifdef SIGCHLD | |
242 | case SIGCHLD: return "child stop or exit"; | |
243 | #endif | |
244 | ||
245 | #ifdef SIGPWR | |
246 | case SIGPWR: return "power fail/restart"; | |
247 | #endif | |
248 | ||
249 | #ifdef SIGURG | |
250 | case SIGURG: return "urgent condition on I/O channel"; | |
251 | #endif | |
252 | ||
253 | #ifdef SIGSTOP | |
254 | case SIGSTOP: return "stop"; | |
255 | #endif | |
256 | ||
257 | #ifdef SIGTSTP | |
258 | case SIGTSTP: return "stop from tty"; | |
259 | #endif | |
260 | ||
261 | #ifdef SIGXCPU | |
262 | case SIGXCPU: return "exceeded CPU limit"; | |
263 | #endif | |
264 | ||
265 | #ifdef SIGXFSZ | |
266 | case SIGXFSZ: return "exceeded file size limit"; | |
267 | #endif | |
268 | ||
269 | default: return "unrecognized signal number"; | |
270 | } | |
271 | } | |
272 | #endif /* OS_STRSIGNAL */ | |
273 | ||
274 | ||
275 | ||
276 | #ifndef OS_STREXIT | |
277 | /************************************************* | |
278 | * Provide strexit() for systems without * | |
279 | *************************************************/ | |
280 | ||
281 | /* Actually, I don't know of any system that has a strexit() function to turn | |
282 | exit codes into text, but this function is implemented this way so that if any | |
283 | OS does have such a thing, it could be used instead of this build-in one. */ | |
284 | ||
1ba28e2b PP |
285 | const char * |
286 | os_strexit(const int n) | |
059ec3d9 PH |
287 | { |
288 | switch (n) | |
289 | { | |
290 | /* On systems without sysexits.h we can assume only those exit codes | |
291 | that are given a default value in exim.h. */ | |
292 | ||
293 | #ifndef NO_SYSEXITS | |
294 | case EX_USAGE: return "(could mean usage or syntax error)"; | |
295 | case EX_DATAERR: return "(could mean error in input data)"; | |
296 | case EX_NOINPUT: return "(could mean input data missing)"; | |
297 | case EX_NOUSER: return "(could mean user nonexistent)"; | |
298 | case EX_NOHOST: return "(could mean host nonexistent)"; | |
299 | case EX_SOFTWARE: return "(could mean internal software error)"; | |
300 | case EX_OSERR: return "(could mean internal operating system error)"; | |
301 | case EX_OSFILE: return "(could mean system file missing)"; | |
302 | case EX_IOERR: return "(could mean input/output error)"; | |
303 | case EX_PROTOCOL: return "(could mean protocol error)"; | |
304 | case EX_NOPERM: return "(could mean permission denied)"; | |
305 | #endif | |
306 | ||
307 | case EX_EXECFAILED: return "(could mean unable to exec or command does not exist)"; | |
308 | case EX_UNAVAILABLE: return "(could mean service or program unavailable)"; | |
309 | case EX_CANTCREAT: return "(could mean can't create output file)"; | |
310 | case EX_TEMPFAIL: return "(could mean temporary error)"; | |
311 | case EX_CONFIG: return "(could mean configuration error)"; | |
312 | default: return ""; | |
313 | } | |
314 | } | |
315 | #endif /* OS_STREXIT */ | |
316 | ||
317 | ||
318 | ||
319 | ||
320 | /*********************************************************** | |
321 | * Load average function * | |
322 | ***********************************************************/ | |
323 | ||
324 | /* Although every Unix seems to have a different way of getting the load | |
325 | average, a number of them have things in common. Some common variants are | |
326 | provided below, but if an OS has unique requirements it can be handled in | |
327 | a specific os.c file. What is required is a function called os_getloadavg | |
328 | which takes no arguments and passes back the load average * 1000 as an int, | |
329 | or -1 if no data is available. */ | |
330 | ||
331 | ||
332 | /* ----------------------------------------------------------------------- */ | |
333 | /* If the OS has got a BSD getloadavg() function, life is very easy. */ | |
334 | ||
335 | #if !defined(OS_LOAD_AVERAGE) && defined(HAVE_BSD_GETLOADAVG) | |
336 | #define OS_LOAD_AVERAGE | |
337 | ||
338 | int | |
339 | os_getloadavg(void) | |
340 | { | |
341 | double avg; | |
342 | int loads = getloadavg (&avg, 1); | |
343 | if (loads != 1) return -1; | |
344 | return (int)(avg * 1000.0); | |
345 | } | |
346 | #endif | |
347 | /* ----------------------------------------------------------------------- */ | |
348 | ||
349 | ||
350 | ||
351 | /* ----------------------------------------------------------------------- */ | |
352 | /* Only SunOS5 has the kstat functions as far as I know, but put the code | |
353 | here as there is the -hal variant, and other systems might follow this road one | |
354 | day. */ | |
355 | ||
356 | #if !defined(OS_LOAD_AVERAGE) && defined(HAVE_KSTAT) | |
357 | #define OS_LOAD_AVERAGE | |
358 | ||
359 | #include <kstat.h> | |
360 | ||
361 | int | |
362 | os_getloadavg(void) | |
363 | { | |
364 | int avg; | |
365 | kstat_ctl_t *kc; | |
366 | kstat_t *ksp; | |
367 | kstat_named_t *kn; | |
368 | ||
369 | if ((kc = kstat_open()) == NULL || | |
370 | (ksp = kstat_lookup(kc, LOAD_AVG_KSTAT_MODULE, 0, LOAD_AVG_KSTAT)) | |
371 | == NULL || | |
372 | kstat_read(kc, ksp, NULL) < 0 || | |
373 | (kn = kstat_data_lookup(ksp, LOAD_AVG_SYMBOL)) == NULL) | |
374 | return -1; | |
375 | ||
376 | avg = (int)(((double)(kn->LOAD_AVG_FIELD)/FSCALE) * 1000.0); | |
377 | ||
378 | kstat_close(kc); | |
379 | return avg; | |
380 | } | |
381 | ||
382 | #endif | |
383 | /* ----------------------------------------------------------------------- */ | |
384 | ||
385 | ||
386 | ||
387 | /* ----------------------------------------------------------------------- */ | |
388 | /* Handle OS where a kernel symbol has to be read from /dev/kmem */ | |
389 | ||
390 | #if !defined(OS_LOAD_AVERAGE) && defined(HAVE_DEV_KMEM) | |
391 | #define OS_LOAD_AVERAGE | |
392 | ||
393 | #include <nlist.h> | |
394 | ||
395 | static int avg_kd = -1; | |
396 | static long avg_offset; | |
397 | ||
398 | int | |
399 | os_getloadavg(void) | |
400 | { | |
401 | LOAD_AVG_TYPE avg; | |
402 | ||
403 | if (avg_kd < 0) | |
404 | { | |
405 | struct nlist nl[2]; | |
406 | nl[0].n_name = LOAD_AVG_SYMBOL; | |
407 | nl[1].n_name = ""; | |
408 | nlist (KERNEL_PATH, nl); | |
409 | avg_offset = (long)nl[0].n_value; | |
410 | avg_kd = open ("/dev/kmem", 0); | |
411 | if (avg_kd < 0) return -1; | |
412 | (void) fcntl(avg_kd, F_SETFD, FD_CLOEXEC); | |
413 | } | |
414 | ||
415 | if (lseek (avg_kd, avg_offset, 0) == -1L | |
416 | || read (avg_kd, (char *)(&avg), sizeof (avg)) != sizeof(avg)) | |
417 | return -1; | |
418 | ||
419 | return (int)(((double)avg/FSCALE)*1000.0); | |
420 | } | |
421 | ||
422 | #endif | |
423 | /* ----------------------------------------------------------------------- */ | |
424 | ||
425 | ||
426 | ||
427 | /* ----------------------------------------------------------------------- */ | |
428 | /* If nothing is known about this OS, then the load average facility is | |
429 | not available. */ | |
430 | ||
431 | #ifndef OS_LOAD_AVERAGE | |
432 | ||
433 | int | |
434 | os_getloadavg(void) | |
435 | { | |
436 | return -1; | |
437 | } | |
438 | ||
439 | #endif | |
440 | ||
441 | /* ----------------------------------------------------------------------- */ | |
442 | ||
443 | ||
444 | ||
445 | #if !defined FIND_RUNNING_INTERFACES | |
446 | /************************************************* | |
447 | * Find all the running network interfaces * | |
448 | *************************************************/ | |
449 | ||
450 | /* Finding all the running interfaces is something that has os-dependent | |
451 | tweaks, even in the IPv4 case, and it gets worse for IPv6, which is why this | |
452 | code is now in the os-dependent source file. There is a common function which | |
453 | works on most OS (except IRIX) for IPv4 interfaces, and, with some variations | |
454 | controlled by macros, on at least one OS for IPv6 and IPv4 interfaces. On Linux | |
455 | with IPv6, the common function is used for the IPv4 interfaces and additional | |
456 | code used for IPv6. Consequently, the real function is called | |
457 | os_common_find_running_interfaces() so that it can be called from the Linux | |
458 | function. On non-Linux systems, the macro for os_find_running_interfaces just | |
459 | calls the common function; on Linux it calls the Linux function. | |
460 | ||
461 | This function finds the addresses of all the running interfaces on the machine. | |
462 | A chain of blocks containing the textual form of the addresses is returned. | |
463 | ||
92f9ced0 NM |
464 | getifaddrs() provides a sane consistent way to query this on modern OSs, |
465 | otherwise fall back to a maze of twisty ioctl() calls | |
466 | ||
467 | Arguments: none | |
468 | Returns: a chain of ip_address_items, each pointing to a textual | |
469 | version of an IP address, with the port field set to zero | |
470 | */ | |
471 | ||
472 | ||
473 | #ifndef NO_FIND_INTERFACES | |
474 | ||
475 | #ifdef HAVE_GETIFADDRS | |
476 | ||
477 | #include <ifaddrs.h> | |
478 | ||
479 | ip_address_item * | |
480 | os_common_find_running_interfaces(void) | |
481 | { | |
482 | struct ifaddrs *ifalist = NULL; | |
483 | ip_address_item *yield = NULL; | |
484 | ip_address_item *last = NULL; | |
485 | ip_address_item *next; | |
486 | ||
487 | if (getifaddrs(&ifalist) != 0) | |
488 | log_write(0, LOG_PANIC_DIE, "Unable to call getifaddrs: %d %s", | |
489 | errno, strerror(errno)); | |
490 | ||
491 | struct ifaddrs *ifa; | |
492 | for (ifa = ifalist; ifa != NULL; ifa = ifa->ifa_next) | |
493 | { | |
494 | if (ifa->ifa_addr->sa_family != AF_INET | |
495 | #if HAVE_IPV6 | |
496 | && ifa->ifa_addr->sa_family != AF_INET6 | |
497 | #endif /* HAVE_IPV6 */ | |
498 | ) | |
499 | continue; | |
500 | ||
501 | if ( !(ifa->ifa_flags & IFF_UP) ) /* Only want 'UP' interfaces */ | |
502 | continue; | |
503 | ||
504 | /* Create a data block for the address, fill in the data, and put it on the | |
505 | chain. */ | |
506 | ||
507 | next = store_get(sizeof(ip_address_item)); | |
508 | next->next = NULL; | |
509 | next->port = 0; | |
510 | (void)host_ntoa(-1, ifa->ifa_addr, next->address, NULL); | |
511 | ||
512 | if (yield == NULL) | |
513 | yield = last = next; | |
514 | else | |
515 | { | |
516 | last->next = next; | |
517 | last = next; | |
518 | } | |
519 | ||
520 | DEBUG(D_interface) debug_printf("Actual local interface address is %s (%s)\n", | |
521 | last->address, ifa->ifa_name); | |
522 | } | |
523 | ||
524 | /* free the list of addresses, and return the chain of data blocks. */ | |
525 | ||
526 | freeifaddrs (ifalist); | |
527 | return yield; | |
528 | } | |
529 | ||
530 | #else /* HAVE_GETIFADDRS */ | |
531 | ||
532 | /* | |
059ec3d9 PH |
533 | Problems: |
534 | ||
535 | (1) Solaris 2 has the SIOGIFNUM call to get the number of interfaces, but | |
536 | other OS (including Solaris 1) appear not to. So just screw in a largeish | |
537 | fixed number, defined by MAX_INTERFACES. This is in the config.h file and | |
538 | can be changed in Local/Makefile. Unfortunately, the www addressing scheme | |
539 | means that some hosts have a very large number of virtual interfaces. Such | |
540 | hosts are recommended to set local_interfaces to avoid problems with this. | |
541 | ||
542 | (2) If the standard code is run on IRIX, it does not return any alias | |
543 | interfaces. There is special purpose code for that operating system, which | |
544 | uses the sysctl() function. The code is in OS/os.c-IRIX, and this code isn't | |
545 | used on that OS. | |
546 | ||
547 | (3) Some experimental/developing OS (e.g. GNU/Hurd) do not have any means | |
548 | of finding the interfaces. If NO_FIND_INTERFACES is set, a fudge-up is used | |
549 | instead. | |
550 | ||
551 | (4) Some operating systems set the IP address in what SIOCGIFCONF returns; | |
552 | others do not, and require SIOCGIFADDR to be called to get it. For most of | |
553 | the former, calling the latter does no harm, but it causes grief on Linux and | |
554 | BSD systems in the case of IP aliasing, so a means of cutting it out is | |
555 | provided. | |
059ec3d9 PH |
556 | */ |
557 | ||
059ec3d9 PH |
558 | /* If there is IPv6 support, and SIOCGLIFCONF is defined, define macros to |
559 | use these new, longer versions of the old IPv4 interfaces. Otherwise, define | |
560 | the macros to use the historical versions. */ | |
561 | ||
562 | #if HAVE_IPV6 && defined SIOCGLIFCONF | |
563 | #define V_ifconf lifconf | |
564 | #define V_ifreq lifreq | |
565 | #define V_GIFADDR SIOCGLIFADDR | |
566 | #define V_GIFCONF SIOCGLIFCONF | |
567 | #define V_GIFFLAGS SIOCGLIFFLAGS | |
568 | #define V_ifc_buf lifc_buf | |
569 | #define V_ifc_family lifc_family | |
570 | #define V_ifc_flags lifc_flags | |
571 | #define V_ifc_len lifc_len | |
572 | #define V_ifr_addr lifr_addr | |
573 | #define V_ifr_flags lifr_flags | |
574 | #define V_ifr_name lifr_name | |
575 | #define V_FAMILY_QUERY AF_UNSPEC | |
576 | #define V_family ss_family | |
577 | #else | |
578 | #define V_ifconf ifconf | |
579 | #define V_ifreq ifreq | |
580 | #define V_GIFADDR SIOCGIFADDR | |
581 | #define V_GIFCONF SIOCGIFCONF | |
582 | #define V_GIFFLAGS SIOCGIFFLAGS | |
583 | #define V_ifc_buf ifc_buf | |
584 | #define V_ifc_family ifc_family | |
585 | #define V_ifc_flags ifc_flags | |
586 | #define V_ifc_len ifc_len | |
587 | #define V_ifr_addr ifr_addr | |
588 | #define V_ifr_flags ifr_flags | |
589 | #define V_ifr_name ifr_name | |
590 | #define V_family sa_family | |
591 | #endif | |
592 | ||
593 | /* In all cases of IPv6 support, use an IPv6 socket. Otherwise (at least on | |
594 | Solaris 8) the call to read the flags doesn't work for IPv6 interfaces. If | |
595 | we find we can't actually make an IPv6 socket, the code will revert to trying | |
596 | an IPv4 socket. */ | |
597 | ||
598 | #if HAVE_IPV6 | |
599 | #define FAMILY AF_INET6 | |
600 | #else | |
601 | #define FAMILY AF_INET | |
602 | #endif | |
603 | ||
604 | /* OK, after all that preliminary stuff, here's the code. */ | |
605 | ||
606 | ip_address_item * | |
607 | os_common_find_running_interfaces(void) | |
608 | { | |
609 | struct V_ifconf ifc; | |
610 | struct V_ifreq ifreq; | |
611 | int vs; | |
612 | ip_address_item *yield = NULL; | |
613 | ip_address_item *last = NULL; | |
614 | ip_address_item *next; | |
615 | char *cp; | |
616 | char buf[MAX_INTERFACES*sizeof(struct V_ifreq)]; | |
617 | struct sockaddr *addrp; | |
618 | size_t len = 0; | |
92f9ced0 | 619 | char addrbuf[512]; |
059ec3d9 PH |
620 | |
621 | /* We have to create a socket in order to do ioctls on it to find out | |
622 | what we want to know. */ | |
623 | ||
624 | if ((vs = socket(FAMILY, SOCK_DGRAM, 0)) < 0) | |
625 | { | |
626 | #if HAVE_IPV6 | |
627 | DEBUG(D_interface) | |
628 | debug_printf("Unable to create IPv6 socket to find interface addresses:\n " | |
629 | "error %d %s\nTrying for an IPv4 socket\n", errno, strerror(errno)); | |
630 | vs = socket(AF_INET, SOCK_DGRAM, 0); | |
631 | if (vs < 0) | |
632 | #endif | |
633 | log_write(0, LOG_PANIC_DIE, "Unable to create IPv4 socket to find interface " | |
634 | "addresses: %d %s", errno, strerror(errno)); | |
635 | } | |
636 | ||
637 | /* Get the interface configuration. Some additional data is required when the | |
638 | new structures are in use. */ | |
639 | ||
640 | ifc.V_ifc_len = sizeof(buf); | |
641 | ifc.V_ifc_buf = buf; | |
642 | ||
643 | #ifdef V_FAMILY_QUERY | |
644 | ifc.V_ifc_family = V_FAMILY_QUERY; | |
645 | ifc.V_ifc_flags = 0; | |
646 | #endif | |
647 | ||
648 | if (ioctl(vs, V_GIFCONF, (char *)&ifc) < 0) | |
649 | log_write(0, LOG_PANIC_DIE, "Unable to get interface configuration: %d %s", | |
650 | errno, strerror(errno)); | |
651 | ||
652 | /* If the buffer is big enough, the ioctl sets the value of ifc.V_ifc_len to | |
653 | the amount actually used. If the buffer isn't big enough, at least on some | |
654 | operating systems, ifc.V_ifc_len still gets set to correspond to the total | |
655 | number of interfaces, even though they don't all fit in the buffer. */ | |
656 | ||
657 | if (ifc.V_ifc_len > sizeof(buf)) | |
658 | { | |
659 | ifc.V_ifc_len = sizeof(buf); | |
660 | DEBUG(D_interface) | |
661 | debug_printf("more than %d interfaces found: remainder not used\n" | |
662 | "(set MAX_INTERFACES in Local/Makefile and rebuild if you want more)\n", | |
663 | MAX_INTERFACES); | |
664 | } | |
665 | ||
666 | /* For each interface, check it is an IP interface, get its flags, and see if | |
667 | it is up; if not, skip. | |
668 | ||
669 | BSD systems differ from others in what SIOCGIFCONF returns. Other systems | |
670 | return a vector of ifreq structures whose size is as defined by the structure. | |
671 | BSD systems allow sockaddrs to be longer than their sizeof, which in turn makes | |
672 | the ifreq structures longer than their sizeof. The code below has its origins | |
673 | in amd and ifconfig; it uses the sa_len field of each sockaddr to determine | |
674 | each item's length. | |
675 | ||
676 | This is complicated by the fact that, at least on BSD systems, the data in the | |
677 | buffer is not guaranteed to be aligned. Thus, we must first copy the basic | |
678 | struct to some aligned memory before looking at the field in the fixed part to | |
679 | find its length, and then recopy the correct length. */ | |
680 | ||
681 | for (cp = buf; cp < buf + ifc.V_ifc_len; cp += len) | |
682 | { | |
683 | memcpy((char *)&ifreq, cp, sizeof(ifreq)); | |
684 | ||
685 | #ifndef HAVE_SA_LEN | |
686 | len = sizeof(struct V_ifreq); | |
687 | ||
688 | #else | |
689 | len = ((ifreq.ifr_addr.sa_len > sizeof(ifreq.ifr_addr))? | |
690 | ifreq.ifr_addr.sa_len : sizeof(ifreq.ifr_addr)) + | |
691 | sizeof(ifreq.V_ifr_name); | |
692 | if (len > sizeof(addrbuf)) | |
693 | log_write(0, LOG_PANIC_DIE, "Address for %s interface is absurdly long", | |
694 | ifreq.V_ifr_name); | |
695 | ||
696 | #endif | |
697 | ||
698 | /* If not an IP interface, skip */ | |
699 | ||
700 | if (ifreq.V_ifr_addr.V_family != AF_INET | |
701 | #if HAVE_IPV6 | |
702 | && ifreq.V_ifr_addr.V_family != AF_INET6 | |
703 | #endif | |
704 | ) continue; | |
705 | ||
706 | /* Get the interface flags, and if the interface is down, continue. Formerly, | |
707 | we treated the inability to get the flags as a panic-die error. However, it | |
708 | seems that on some OS (Solaris 9 being the case noted), it is possible to | |
709 | have an interface in this list for which this call fails because the | |
710 | interface hasn't been "plumbed" to any protocol (IPv4 or IPv6). Therefore, | |
711 | we now just treat this case as "down" as well. */ | |
712 | ||
713 | if (ioctl(vs, V_GIFFLAGS, (char *)&ifreq) < 0) | |
714 | { | |
715 | continue; | |
716 | /************* | |
717 | log_write(0, LOG_PANIC_DIE, "Unable to get flags for %s interface: %d %s", | |
718 | ifreq.V_ifr_name, errno, strerror(errno)); | |
719 | *************/ | |
720 | } | |
721 | if ((ifreq.V_ifr_flags & IFF_UP) == 0) continue; | |
722 | ||
723 | /* On some operating systems we have to get the IP address of the interface | |
214e2000 PH |
724 | by another call. On others, it's already there, but we must copy the full |
725 | length because we only copied the basic length above, and anyway, | |
726 | GIFFLAGS may have wrecked the data. */ | |
059ec3d9 PH |
727 | |
728 | #ifndef SIOCGIFCONF_GIVES_ADDR | |
729 | if (ioctl(vs, V_GIFADDR, (char *)&ifreq) < 0) | |
730 | log_write(0, LOG_PANIC_DIE, "Unable to get IP address for %s interface: " | |
731 | "%d %s", ifreq.V_ifr_name, errno, strerror(errno)); | |
732 | addrp = &ifreq.V_ifr_addr; | |
733 | ||
734 | #else | |
214e2000 PH |
735 | memcpy(addrbuf, cp + offsetof(struct V_ifreq, V_ifr_addr), |
736 | len - sizeof(ifreq.V_ifr_name)); | |
059ec3d9 PH |
737 | addrp = (struct sockaddr *)addrbuf; |
738 | #endif | |
739 | ||
740 | /* Create a data block for the address, fill in the data, and put it on the | |
741 | chain. */ | |
742 | ||
743 | next = store_get(sizeof(ip_address_item)); | |
744 | next->next = NULL; | |
745 | next->port = 0; | |
746 | (void)host_ntoa(-1, addrp, next->address, NULL); | |
747 | ||
748 | if (yield == NULL) yield = last = next; else | |
749 | { | |
750 | last->next = next; | |
751 | last = next; | |
752 | } | |
753 | ||
754 | DEBUG(D_interface) debug_printf("Actual local interface address is %s (%s)\n", | |
755 | last->address, ifreq.V_ifr_name); | |
756 | } | |
757 | ||
758 | /* Close the socket, and return the chain of data blocks. */ | |
759 | ||
f1e894f3 | 760 | (void)close(vs); |
059ec3d9 PH |
761 | return yield; |
762 | } | |
763 | ||
92f9ced0 NM |
764 | #endif /* HAVE_GETIFADDRS */ |
765 | ||
059ec3d9 PH |
766 | #else /* NO_FIND_INTERFACES */ |
767 | ||
768 | /* Some experimental or developing OS (e.g. GNU/Hurd) do not have the ioctls, | |
769 | and there is no other way to get a list of the (IP addresses of) local | |
770 | interfaces. We just return the loopback address(es). */ | |
771 | ||
772 | ip_address_item * | |
773 | os_common_find_running_interfaces(void) | |
774 | { | |
775 | ip_address_item *yield = store_get(sizeof(address_item)); | |
776 | yield->address = US"127.0.0.1"; | |
777 | yield->port = 0; | |
778 | yield->next = NULL; | |
779 | ||
780 | #if HAVE_IPV6 | |
781 | yield->next = store_get(sizeof(address_item)); | |
782 | yield->next->address = US"::1"; | |
783 | yield->next->port = 0; | |
784 | yield->next->next = NULL; | |
785 | #endif | |
786 | ||
787 | DEBUG(D_interface) debug_printf("Unable to find local interface addresses " | |
788 | "on this OS: returning loopback address(es)\n"); | |
789 | return yield; | |
790 | } | |
791 | ||
792 | #endif /* NO_FIND_INTERFACES */ | |
793 | #endif /* FIND_RUNNING_INTERFACES */ | |
794 | ||
795 | ||
796 | ||
797 | ||
5bfb4cdf PP |
798 | /* ----------------------------------------------------------------------- */ |
799 | ||
800 | /*********************************************************** | |
801 | * DNS Resolver Base Finder * | |
802 | ***********************************************************/ | |
803 | ||
804 | /* We need to be able to set options for the system resolver(5), historically | |
805 | made available as _res. At least one OS (NetBSD) now no longer provides this | |
806 | directly, instead making you call a function per thread to get a handle. | |
807 | Other OSs handle thread-safe resolver differently, in ways which fail if the | |
808 | programmer creates their own structs. */ | |
809 | ||
0a3df1d6 | 810 | #if !defined(OS_GET_DNS_RESOLVER_RES) && !defined(COMPILE_UTILITY) |
5bfb4cdf PP |
811 | |
812 | #include <resolv.h> | |
813 | ||
814 | /* confirmed that res_state is typedef'd as a struct* on BSD and Linux, will | |
815 | find out how unportable it is on other OSes, but most resolver implementations | |
816 | should be descended from ISC's bind. | |
817 | ||
818 | Linux and BSD do: | |
819 | define _res (*__res_state()) | |
820 | identically. We just can't rely on __foo functions. It's surprising that use | |
821 | of _res has been as portable as it has, for so long. | |
822 | ||
823 | So, since _res works everywhere, and everything can decode the struct, I'm | |
824 | going to gamble that res_state is a typedef everywhere and use that as the | |
825 | return type. | |
826 | */ | |
827 | ||
828 | res_state | |
829 | os_get_dns_resolver_res(void) | |
830 | { | |
831 | return &_res; | |
832 | } | |
833 | ||
834 | #endif /* OS_GET_DNS_RESOLVER_RES */ | |
835 | ||
836 | ||
837 | /* ----------------------------------------------------------------------- */ | |
838 | ||
839 | ||
840 | ||
841 | ||
059ec3d9 PH |
842 | |
843 | /************************************************* | |
844 | ************************************************** | |
845 | * Stand-alone test program * | |
846 | ************************************************** | |
847 | *************************************************/ | |
848 | ||
849 | ||
850 | #ifdef STAND_ALONE | |
851 | ||
852 | #ifdef CLOCKS_PER_SEC | |
853 | #define REAL_CLOCK_TICK CLOCKS_PER_SEC | |
854 | #else | |
855 | #ifdef CLK_TCK | |
856 | #define REAL_CLOCK_TICK CLK_TCK | |
857 | #else | |
858 | #define REAL_CLOCK_TICK 1000000 /* SunOS4 */ | |
859 | #endif | |
860 | #endif | |
861 | ||
862 | ||
863 | int main(int argc, char **argv) | |
864 | { | |
865 | char buffer[128]; | |
866 | int fd = fileno(stdin); | |
867 | int rc; | |
868 | ||
869 | printf("Testing restarting signal; wait for handler message, then type a line\n"); | |
870 | strcpy(buffer, "*** default ***\n"); | |
871 | os_restarting_signal(SIGALRM, sigalrm_handler); | |
872 | alarm(2); | |
873 | if ((rc = read(fd, buffer, sizeof(buffer))) < 0) | |
874 | printf("No data read\n"); | |
875 | else | |
876 | { | |
877 | buffer[rc] = 0; | |
878 | printf("Read: %s", buffer); | |
879 | } | |
880 | alarm(0); | |
881 | ||
882 | printf("Testing non-restarting signal; should read no data after handler message\n"); | |
883 | strcpy(buffer, "*** default ***\n"); | |
884 | os_non_restarting_signal(SIGALRM, sigalrm_handler); | |
885 | alarm(2); | |
886 | if ((rc = read(fd, buffer, sizeof(buffer))) < 0) | |
887 | printf("No data read\n"); | |
888 | else | |
889 | { | |
890 | buffer[rc] = 0; | |
891 | printf("Read: %s", buffer); | |
892 | } | |
893 | alarm(0); | |
894 | ||
895 | printf("Testing load averages (last test - ^C to kill)\n"); | |
896 | for (;;) | |
897 | { | |
898 | int avg; | |
899 | clock_t used; | |
900 | clock_t before = clock(); | |
901 | avg = os_getloadavg(); | |
902 | used = clock() - before; | |
903 | printf("cpu time = %.2f ", (double)used/REAL_CLOCK_TICK); | |
904 | if (avg < 0) | |
905 | { | |
906 | printf("load average not available\n"); | |
907 | break; | |
908 | } | |
909 | printf("load average = %.2f\n", (double)avg/1000.0); | |
910 | sleep(2); | |
911 | } | |
912 | return 0; | |
913 | } | |
914 | ||
915 | #endif | |
916 | ||
917 | /* End of os.c */ |