1/*
2 * dhcpcd - DHCP client daemon
3 * Copyright (c) 2006-2019 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
35#include "config.h"
36#include "defs.h"
37#include "dhcpcd.h"
38
39#ifndef HOSTNAME_MAX_LEN
40#define HOSTNAME_MAX_LEN 250 /* 255 - 3 (FQDN) - 2 (DNS enc) */
41#endif
42
43#ifndef MIN
44#define MIN(a,b) ((/*CONSTCOND*/(a)<(b))?(a):(b))
45#define MAX(a,b) ((/*CONSTCOND*/(a)>(b))?(a):(b))
46#endif
47
48#define UNCONST(a) ((void *)(unsigned long)(const void *)(a))
49#define STRINGIFY(a) #a
50#define TOSTRING(a) STRINGIFY(a)
51#define UNUSED(a) (void)(a)
52
53#define ROUNDUP4(a) (1 + (((a) - 1) | 3))
54#define ROUNDUP8(a) (1 + (((a) - 1) | 7))
55
56#define USEC_PER_SEC 1000000L
57#define USEC_PER_NSEC 1000L
58#define NSEC_PER_SEC 1000000000L
59#define NSEC_PER_MSEC 1000000L
60#define MSEC_PER_SEC 1000L
61#define CSEC_PER_SEC 100L
62#define NSEC_PER_CSEC 10000000L
63
64/* Some systems don't define timespec macros */
65#ifndef timespecclear
66#define timespecclear(tsp) (tsp)->tv_sec = (time_t)((tsp)->tv_nsec = 0L)
67#define timespecisset(tsp) ((tsp)->tv_sec || (tsp)->tv_nsec)
68#define timespeccmp(tsp, usp, cmp) \
69 (((tsp)->tv_sec == (usp)->tv_sec) ? \
70 ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \
71 ((tsp)->tv_sec cmp (usp)->tv_sec))
72#define timespecadd(tsp, usp, vsp) \
73 do { \
74 (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \
75 (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \
76 if ((vsp)->tv_nsec >= 1000000000L) { \
77 (vsp)->tv_sec++; \
78 (vsp)->tv_nsec -= 1000000000L; \
79 } \
80 } while (/* CONSTCOND */ 0)
81#define timespecsub(tsp, usp, vsp) \
82 do { \
83 (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \
84 (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \
85 if ((vsp)->tv_nsec < 0) { \
86 (vsp)->tv_sec--; \
87 (vsp)->tv_nsec += 1000000000L; \
88 } \
89 } while (/* CONSTCOND */ 0)
90#endif
91
92#define timespec_to_double(tv) \
93 ((double)(tv)->tv_sec + (double)((tv)->tv_nsec) / 1000000000.0)
94#define timespecnorm(tv) do { \
95 while ((tv)->tv_nsec >= NSEC_PER_SEC) { \
96 (tv)->tv_sec++; \
97 (tv)->tv_nsec -= NSEC_PER_SEC; \
98 } \
99} while (0 /* CONSTCOND */);
100#define ts_to_ms(ms, tv) do { \
101 ms = (tv)->tv_sec * MSEC_PER_SEC; \
102 ms += (tv)->tv_nsec / NSEC_PER_MSEC; \
103} while (0 /* CONSTCOND */);
104#define ms_to_ts(tv, ms) do { \
105 (tv)->tv_sec = ms / MSEC_PER_SEC; \
106 (tv)->tv_nsec = (suseconds_t)(ms - ((tv)->tv_sec * MSEC_PER_SEC)) \
107 * NSEC_PER_MSEC; \
108} while (0 /* CONSTCOND */);
109
110#ifndef TIMEVAL_TO_TIMESPEC
111#define TIMEVAL_TO_TIMESPEC(tv, ts) do { \
112 (ts)->tv_sec = (tv)->tv_sec; \
113 (ts)->tv_nsec = (tv)->tv_usec * USEC_PER_NSEC; \
114} while (0 /* CONSTCOND */)
115#endif
116
117#if __GNUC__ > 2 || defined(__INTEL_COMPILER)
118# ifndef __packed
119# define __packed __attribute__((__packed__))
120# endif
121# ifndef __unused
122# define __unused __attribute__((__unused__))
123# endif
124#else
125# ifndef __packed
126# define __packed
127# endif
128# ifndef __unused
129# define __unused
130# endif
131#endif
132
133#ifndef __fallthrough
134# if __GNUC__ >= 7
135# define __fallthrough __attribute__((fallthrough))
136# else
137# define __fallthrough
138# endif
139#endif
140
141/*
142 * Compile Time Assertion.
143 */
144#ifndef __CTASSERT
145# ifdef __COUNTER__
146# define __CTASSERT(x) __CTASSERT0(x, __ctassert, __COUNTER__)
147# else
148# define __CTASSERT(x) __CTASSERT99(x, __INCLUDE_LEVEL__, __LINE__)
149# define __CTASSERT99(x, a, b) __CTASSERT0(x, __CONCAT(__ctassert,a), \
150 __CONCAT(_,b))
151# endif
152# define __CTASSERT0(x, y, z) __CTASSERT1(x, y, z)
153# define __CTASSERT1(x, y, z) typedef char y ## z[/*CONSTCOND*/(x) ? 1 : -1] __unused
154#endif
155
156#ifndef __arraycount
157# define __arraycount(__x) (sizeof(__x) / sizeof(__x[0]))
158#endif
159
160/* We don't really need this as our supported systems define __restrict
161 * automatically for us, but it is here for completeness. */
162#ifndef __restrict
163# if defined(__lint__)
164# define __restrict
165# elif __STDC_VERSION__ >= 199901L
166# define __restrict restrict
167# elif !(2 < __GNUC__ || (2 == __GNU_C && 95 <= __GNUC_VERSION__))
168# define __restrict
169# endif
170#endif
171
172void get_line_free(void);
173extern int clock_monotonic;
174int get_monotonic(struct timespec *);
175
176ssize_t setvar(char **, const char *, const char *, const char *);
177ssize_t setvard(char **, const char *, const char *, size_t);
178ssize_t addvar(char ***, const char *, const char *, const char *);
179ssize_t addvard(char ***, const char *, const char *, size_t);
180
181const char *hwaddr_ntoa(const void *, size_t, char *, size_t);
182size_t hwaddr_aton(uint8_t *, const char *);
183size_t read_hwaddr_aton(uint8_t **, const char *);
184#endif
185