1 /*
2  * dhcpcd - DHCP client daemon
3  * Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
4  * All rights reserved
5 
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #ifndef COMMON_H
29 #define COMMON_H
30 
31 #include <sys/param.h>
32 #include <sys/time.h>
33 #include <stdio.h>
34 #include <syslog.h>
35 
36 #include "config.h"
37 #include "defs.h"
38 #include "dhcpcd.h"
39 
40 #ifndef HOSTNAME_MAX_LEN
41 #define HOSTNAME_MAX_LEN	250	/* 255 - 3 (FQDN) - 2 (DNS enc) */
42 #endif
43 
44 #ifndef MIN
45 #define MIN(a,b)		((/*CONSTCOND*/(a)<(b))?(a):(b))
46 #define MAX(a,b)		((/*CONSTCOND*/(a)>(b))?(a):(b))
47 #endif
48 
49 #define UNCONST(a)		((void *)(unsigned long)(const void *)(a))
50 #define STRINGIFY(a)		#a
51 #define TOSTRING(a)		STRINGIFY(a)
52 #define UNUSED(a)		(void)(a)
53 
54 #define USEC_PER_SEC		1000000L
55 #define USEC_PER_NSEC		1000L
56 #define NSEC_PER_SEC		1000000000L
57 #define MSEC_PER_SEC		1000L
58 #define MSEC_PER_NSEC		1000000L
59 
60 /* Some systems don't define timespec macros */
61 #ifndef timespecclear
62 #define timespecclear(tsp)      (tsp)->tv_sec = (time_t)((tsp)->tv_nsec = 0L)
63 #define timespecisset(tsp)      ((tsp)->tv_sec || (tsp)->tv_nsec)
64 #define timespeccmp(tsp, usp, cmp)                                      \
65         (((tsp)->tv_sec == (usp)->tv_sec) ?                             \
66             ((tsp)->tv_nsec cmp (usp)->tv_nsec) :                       \
67             ((tsp)->tv_sec cmp (usp)->tv_sec))
68 #define timespecadd(tsp, usp, vsp)                                      \
69         do {                                                            \
70                 (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec;          \
71                 (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec;       \
72                 if ((vsp)->tv_nsec >= 1000000000L) {                    \
73                         (vsp)->tv_sec++;                                \
74                         (vsp)->tv_nsec -= 1000000000L;                  \
75                 }                                                       \
76         } while (/* CONSTCOND */ 0)
77 #define timespecsub(tsp, usp, vsp)                                      \
78         do {                                                            \
79                 (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec;          \
80                 (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec;       \
81                 if ((vsp)->tv_nsec < 0) {                               \
82                         (vsp)->tv_sec--;                                \
83                         (vsp)->tv_nsec += 1000000000L;                  \
84                 }                                                       \
85         } while (/* CONSTCOND */ 0)
86 #endif
87 
88 #define timespec_to_double(tv)						     \
89 	((double)(tv)->tv_sec + (double)((tv)->tv_nsec) / 1000000000.0)
90 #define timespecnorm(tv) do {						     \
91 	while ((tv)->tv_nsec >=  NSEC_PER_SEC) {			     \
92 		(tv)->tv_sec++;						     \
93 		(tv)->tv_nsec -= NSEC_PER_SEC;				     \
94 	}								     \
95 } while (0 /* CONSTCOND */);
96 #define ts_to_ms(ms, tv) do {						     \
97 	ms = (tv)->tv_sec * MSEC_PER_SEC;				     \
98 	ms += (tv)->tv_nsec / MSEC_PER_NSEC;				     \
99 } while (0 /* CONSTCOND */);
100 #define ms_to_ts(tv, ms) do {						     \
101 	(tv)->tv_sec = ms / MSEC_PER_SEC;				     \
102 	(tv)->tv_nsec = (suseconds_t)(ms - ((tv)->tv_sec * MSEC_PER_SEC))    \
103 	    * MSEC_PER_NSEC;						     \
104 } while (0 /* CONSTCOND */);
105 
106 #ifndef TIMEVAL_TO_TIMESPEC
107 #define	TIMEVAL_TO_TIMESPEC(tv, ts) do {				\
108 	(ts)->tv_sec = (tv)->tv_sec;					\
109 	(ts)->tv_nsec = (tv)->tv_usec * USEC_PER_NSEC;			\
110 } while (0 /* CONSTCOND */)
111 #endif
112 
113 #if __GNUC__ > 2 || defined(__INTEL_COMPILER)
114 # ifndef __dead
115 #  define __dead __attribute__((__noreturn__))
116 # endif
117 # ifndef __packed
118 #  define __packed   __attribute__((__packed__))
119 # endif
120 # ifndef __printflike
121 #  define __printflike(a, b) __attribute__((format(printf, a, b)))
122 # endif
123 # ifndef __unused
124 #  define __unused   __attribute__((__unused__))
125 # endif
126 #else
127 # ifndef __dead
128 #  define __dead
129 # endif
130 # ifndef __packed
131 #  define __packed
132 # endif
133 # ifndef __printflike
134 #  define __printflike
135 # endif
136 # ifndef __unused
137 #  define __unused
138 # endif
139 #endif
140 
141 /* We don't really need this as our supported systems define __restrict
142  * automatically for us, but it is here for completeness. */
143 #ifndef __restrict
144 # if defined(__lint__)
145 #  define __restrict
146 # elif __STDC_VERSION__ >= 199901L
147 #  define __restrict restrict
148 # elif !(2 < __GNUC__ || (2 == __GNU_C && 95 <= __GNUC_VERSION__))
149 #  define __restrict
150 # endif
151 #endif
152 
153 void get_line_free(void);
154 const char *get_hostname(char *, size_t, int);
155 extern int clock_monotonic;
156 int get_monotonic(struct timespec *);
157 
158 /* We could shave a few k off the binary size by just using the
159  * syslog(3) interface.
160  * However, this results in a ugly output on the command line
161  * and relies on syslogd(8) starting before dhcpcd which is not
162  * always the case. */
163 #ifndef USE_LOGFILE
164 # define USE_LOGFILE 1
165 #endif
166 #if USE_LOGFILE
167 void logger_open(struct dhcpcd_ctx *);
168 #define logger_mask(ctx, lvl) setlogmask((lvl))
169 __printflike(3, 4) void logger(struct dhcpcd_ctx *, int, const char *, ...);
170 void logger_close(struct dhcpcd_ctx *);
171 #else
172 #define logger_open(ctx) openlog(PACKAGE, LOG_PERROR | LOG_PID, LOG_DAEMON)
173 #define logger_mask(ctx, lvl) setlogmask((lvl))
174 #define logger(ctx, pri, fmt, ...)			\
175 	do {						\
176 		UNUSED((ctx));				\
177 		syslog((pri), (fmt), ##__VA_ARGS__);	\
178 	} while (0 /*CONSTCOND */)
179 #define logger_close(ctx) closelog()
180 #endif
181 
182 ssize_t setvar(struct dhcpcd_ctx *,
183     char ***, const char *, const char *, const char *);
184 ssize_t setvard(struct dhcpcd_ctx *,
185     char ***, const char *, const char *, size_t);
186 time_t uptime(void);
187 
188 char *hwaddr_ntoa(const unsigned char *, size_t, char *, size_t);
189 size_t hwaddr_aton(unsigned char *, const char *);
190 #endif
191