Dibbler - a portable DHCPv6  1.0.2RC1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Portable.h
Go to the documentation of this file.
1 /*
2  * Dibbler - a portable DHCPv6
3  *
4  * authors: Tomasz Mrugalski <thomson@klub.com.pl>
5  * Marek Senderski <msend@o2.pl>
6  * changes: Krzysztof Wnuk <keczi@poczta.onet.pl>
7  * Michal Kowalczuk <michal@kowalczuk.eu>
8  *
9  * Released under GNU GPL v2 licence
10  *
11  */
12 
13 #ifndef PORTABLE_H
14 #define PORTABLE_H
15 
16 #define DIBBLER_VERSION "1.0.2RC1"
17 
18 #define DIBBLER_COPYRIGHT1 "| Dibbler - a portable DHCPv6, version " DIBBLER_VERSION
19 #define DIBBLER_COPYRIGHT2 "| Authors : Tomasz Mrugalski<thomson(at)klub.com.pl>,Marek Senderski<msend(at)o2.pl>"
20 #define DIBBLER_COPYRIGHT3 "| Licence : GNU GPL v2 only. Developed at Gdansk University of Technology."
21 #define DIBBLER_COPYRIGHT4 "| Homepage: http://klub.com.pl/dhcpv6/"
22 
23 #ifdef WIN32
24 #include <winsock2.h>
25 #define strcasecmp strcmpi
26 #endif
27 #if defined(LINUX) || defined(BSD)
28 #include <arpa/inet.h>
29 #endif
30 
31 #if defined(LINUX)
32 # include <sys/select.h>
33 #endif
34 
35 #include <stdint.h>
36 #include <unistd.h>
37 
38 /* this should look like this:
39 uint16_t readUint16(uint8_t* buf);
40 uint8_t * writeUint16(uint8_t* buf, uint16_t word);
41 uint32_t readUint32(uint8_t* buf);
42 uint8_t* writeUint32(uint8_t* buf, uint32_t dword);
43 uint64_t readUint64(uint8_t* buf);
44 uint8_t* writeUint64(uint8_t* buf, uint64_t qword); */
45 
46 /* due to poor type usage (char* instead of uint8_t*), we need to stick with
47  char* for now. Changing to uint8_t would require rewriting large parts of the code */
48 #define BUFFER_TYPE char
49 
50 #ifdef __cplusplus
51 extern "C" {
52 #endif
53  uint8_t readUint8(const BUFFER_TYPE* buf);
54  BUFFER_TYPE* writeUint8(BUFFER_TYPE* buf, uint8_t octet);
55  uint16_t readUint16(const BUFFER_TYPE * buf);
57  uint32_t readUint32(const BUFFER_TYPE * buf);
59  uint64_t readUint64(const BUFFER_TYPE * buf);
60  BUFFER_TYPE * writeUint64(BUFFER_TYPE * buf, uint64_t qword);
61  BUFFER_TYPE* writeData(BUFFER_TYPE* buf, BUFFER_TYPE* data, size_t len);
62 #ifdef __cplusplus
63 }
64 #endif
65 
66 #define DEFAULT_UMASK 027
67 
68 /**********************************************************************/
69 /*** data structures **************************************************/
70 /**********************************************************************/
71 
72 #ifndef MAX_IFNAME_LENGTH
73 #define MAX_IFNAME_LENGTH 255
74 #endif
75 
76 /* Structure used for interface name reporting */
77 struct iface {
78  char name[MAX_IFNAME_LENGTH]; /* interface name */
79  int id; /* interface ID (often called ifindex) */
80  int hardwareType; /* type of hardware (see RFC 826) */
81  char mac[255]; /* link layer address */
82  int maclen; /* length of link layer address */
83  char *linkaddr; /* assigned IPv6 link local addresses */
84  int linkaddrcount; /* number of assigned IPv6 link local addresses */
85  char *globaladdr; /* global IPv6 addresses */
86  int globaladdrcount; /* number of global IPV6 addresses */
87  int link_state; /* used in link change detection routines */
88  unsigned int flags; /* look IF_xxx in portable.h */
89  unsigned char m_bit; /* M bit in RA received? */
90  unsigned char o_bit; /* O bit in RA received? */
91  struct iface* next; /* structure describing next iface in system */
92 };
93 
94 #define MAX_LINK_STATE_CHANGES_AT_ONCE 16
95 
96 /* This constant defines whether addresses configured on Linux are added with
97  preferred and valid lifetimes. There seems to be a bug in the kernel that
98  adds the addresses with lifetimes only if they're not duplicated, whereas
99  the expected behavior is the kernel to add them always, but report them as
100  duplicate if needed. This causes the client to get confused if the address
101  is duplicate.
102 
103  Since adding the address without lifetimes in a safer bet (the Duplicate Address
104  Detection will work), this is the default. If you really need to add adresses
105  with lifetimes, please set this to 1, but be aware that DAD may not work. */
106 #define ADD_ADDRESSES_WITH_LIFETIMES 0
107 
109 {
110  int ifindex[MAX_LINK_STATE_CHANGES_AT_ONCE]; /* indexes of interfaces that has changed.
111  Only non-zero values will be used */
113  int cnt; /* number of iterface indexes filled */
114 };
115 
116 /**********************************************************************/
117 /*** file setup/default paths *****************************************/
118 /**********************************************************************/
119 
120 #define CLNTCFGMGR_FILE "client-CfgMgr.xml"
121 #define CLNTIFACEMGR_FILE "client-IfaceMgr.xml"
122 #define CLNTDUID_FILE "client-duid"
123 #define CLNTADDRMGR_FILE "client-AddrMgr.xml"
124 #define CLNTTRANSMGR_FILE "client-TransMgr.xml"
125 
126 #define SRVCFGMGR_FILE "server-CfgMgr.xml"
127 #define SRVIFACEMGR_FILE "server-IfaceMgr.xml"
128 #define SRVDUID_FILE "server-duid"
129 #define SRVADDRMGR_FILE "server-AddrMgr.xml"
130 #define SRVTRANSMGR_FILE "server-TransMgr.xml"
131 #define SRVCACHE_FILE "server-cache.xml"
132 
133 #define RELCFGMGR_FILE "relay-CfgMgr.xml"
134 #define RELIFACEMGR_FILE "relay-IfaceMgr.xml"
135 #define RELTRANSMGR_FILE "relay-TransMgr.xml"
136 
137 #define REQIFACEMGR_FILE "requestor-IfaceMgr.xml"
138 
139 #define DNSUPDATE_DEFAULT_TTL "2h"
140 #define DNSUPDATE_DEFAULT_TIMEOUT 1000 /* in ms */
141 #define INACTIVE_MODE_INTERVAL 3 /* 3 seconds */
142 
143 #define REQLOG_FILE "dibbler-requestor.log"
144 
145 #ifdef WIN32
146 #define DEFAULT_WORKDIR ".\\"
147 #define DEFAULT_SCRIPT ""
148 #define DEFAULT_CLNTCONF_FILE "client.conf"
149 #define SRVCONF_FILE "server.conf"
150 #define RELCONF_FILE "relay.conf"
151 #define DEFAULT_CLNTLOG_FILE "dibbler-client.log"
152 #define SRVLOG_FILE "dibbler-server.log"
153 #define RELLOG_FILE "dibbler-relay.log"
154 #define CLNT_AAASPI_FILE "AAA-SPI"
155 #define SRV_KEYMAP_FILE "keys-mapping"
156 #define NULLFILE "nul"
157 /* specifies if client should remove any configured DNS servers when configuring
158  DNS servers for the first time. This makes sense on WIN32 only. */
159 #define FLUSH_OTHER_CONFIGURED_DNS_SERVERS true
160 #endif
161 
162 #ifndef DEFAULT_WORKDIR
163 #if defined(BSD)
164 #define DEFAULT_WORKDIR "/var/db/dibbler"
165 #else
166 #if !defined(WIN32)
167 #define DEFAULT_WORKDIR "/var/lib/dibbler"
168 #endif
169 #endif
170 #endif
171 
172 #if defined(LINUX) || defined(BSD) || defined(SUNOS)
173 #define DEFAULT_CLNTCONF_FILE "/etc/dibbler/client.conf"
174 #define DEFAULT_CLNTPID_FILE "/var/lib/dibbler/client.pid"
175 #define DEFAULT_CLNTLOG_FILE "/var/log/dibbler/dibbler-client.log"
176 
177 #define DEFAULT_SCRIPT ""
178 #define SRVCONF_FILE "/etc/dibbler/server.conf"
179 #define RELCONF_FILE "/etc/dibbler/relay.conf"
180 #define RESOLVCONF_FILE "/etc/resolv.conf"
181 #define NTPCONF_FILE "/etc/ntp.conf"
182 #define RADVD_FILE "/etc/dibbler/radvd.conf"
183 
184 #if defined(BSD)
185 #define SRVPID_FILE "/var/run/dibbler-server.pid"
186 #define RELPID_FILE "/var/run/dibbler-relay.pid"
187 #define CLNT_AAASPI_FILE "/var/db/dibbler/AAA/AAA-SPI"
188 #define SRV_KEYMAP_FILE "/var/db/dibbler/AAA/keys-mapping"
189 #else
190 #define SRVPID_FILE "/var/lib/dibbler/server.pid"
191 #define RELPID_FILE "/var/lib/dibbler/relay.pid"
192 #define CLNT_AAASPI_FILE "/var/lib/dibbler/AAA/AAA-SPI"
193 #define SRV_KEYMAP_FILE "/var/lib/dibbler/AAA/keys-mapping"
194 #endif
195 
196 #define SRVLOG_FILE "/var/log/dibbler/dibbler-server.log"
197 #define RELLOG_FILE "/var/log/dibbler/dibbler-relay.log"
198 #define NULLFILE "/dev/null"
199 
200 /* those defines were initially used on Linux only, but hopefully
201  they will work on other Posix systems as well */
202 #define RESOLVCONF "/sbin/resolvconf"
203 #define TIMEZONE_FILE "/etc/localtime"
204 #define TIMEZONES_DIR "/usr/share/zoneinfo"
205 
206 /* specifies if client should remove any configured DNS servers when configuring
207  DNS servers for the first time. This makes sense on WIN32 only. */
208 #define FLUSH_OTHER_CONFIGURED_DNS_SERVERS false
209 #endif
210 
211 /* --- options --- */
212 #define OPTION_DNS_SERVERS_FILENAME "option-dns-servers"
213 #define OPTION_DOMAINS_FILENAME "option-domains"
214 #define OPTION_NTP_SERVERS_FILENAME "option-ntp-servers"
215 #define OPTION_TIMEZONE_FILENAME "option-timezone"
216 #define OPTION_SIP_SERVERS_FILENAME "option-sip-servers"
217 #define OPTION_SIP_DOMAINS_FILENAME "option-sip-domains"
218 #define OPTION_NIS_SERVERS_FILENAME "option-nis-servers"
219 #define OPTION_NIS_DOMAIN_FILENAME "option-nis-domain"
220 #define OPTION_NISP_SERVERS_FILENAME "option-nisplus-servers"
221 #define OPTION_NISP_DOMAIN_FILENAME "option-nisplus-domain"
222 
223 /* --- bulk leasequery --- */
224 #define BULKLQ_ACCEPT false
225 #define BULKLQ_TCP_PORT 547
226 #define BULKLQ_MAX_CONNS 10
227 #define BULKLQ_TIMEOUT 300
228 
229 /* ********************************************************************** */
230 /* *** interface flags ************************************************** */
231 /* ********************************************************************** */
232 /* those flags are used to parse flags in the structure
233  returned by if_list_get(). They are highly system specific.
234  Posix systems use values imported from headers */
235 
236 #ifdef WIN32
237 #define IFF_RUNNING IFF_UP
238 /* those defines are in ws2ipdef.h
239 #define IFF_UP 0x1
240 #define IFF_MULTICAST 0x4
241 #define IFF_LOOPBACK 0x8 */
242 #endif
243 
244 /* ********************************************************************** */
245 /* *** low-level error codes ******************************************** */
246 /* ********************************************************************** */
247 #define LOWLEVEL_NO_ERROR 0
248 #define LOWLEVEL_ERROR_UNSPEC -1
249 #define LOWLEVEL_ERROR_BIND_IFACE -2
250 #define LOWLEVEL_ERROR_BIND_FAILED -4
251 #define LOWLEVEL_ERROR_MCAST_HOPS -5
252 #define LOWLEVEL_ERROR_MCAST_MEMBERSHIP -6
253 #define LOWLEVEL_ERROR_GETADDRINFO -7
254 #define LOWLEVEL_ERROR_SOCK_OPTS -8
255 #define LOWLEVEL_ERROR_REUSE_FAILED -9
256 #define LOWLEVEL_ERROR_FILE -10
257 #define LOWLEVEL_ERROR_SOCKET -11
258 #define LOWLEVEL_ERROR_NOT_IMPLEMENTED -12
259 
260 #define LOWLEVEL_TENTATIVE_YES 1
261 #define LOWLEVEL_TENTATIVE_NO 0
262 #define LOWLEVEL_TENTATIVE_DONT_KNOW -1
263 
264 /* ********************************************************************** */
265 /* *** time related functions ******************************************* */
266 /* ********************************************************************** */
267 
268 #ifdef WIN32
269 #define strncasecmp _strnicmp
270 #include <winsock2.h>
271 #include <windows.h>
272 #include <time.h>
273 #endif
274 
275 /* ********************************************************************** */
276 /* *** interface/socket low level functions ***************************** */
277 /* ********************************************************************** */
278 
279 #ifdef __cplusplus
280 extern "C" {
281 #endif
282 
283  int lowlevelInit();
284  int lowlevelExit();
285 
286  /* get list of interfaces */
287  extern struct iface * if_list_get();
288  extern void if_list_release(struct iface * list);
289 
290  /* add address to interface */
291  extern int ipaddr_add(const char* ifacename, int ifindex, const char* addr,
292 unsigned long pref, unsigned long valid, int prefixLength);
293  extern int ipaddr_update(const char* ifacename, int ifindex, const char* addr,
294  unsigned long pref, unsigned long valid, int prefixLength);
295  extern int ipaddr_del(const char* ifacename, int ifindex, const char* addr, int prefixLength);
296 
297  /* add socket to interface */
298  extern int sock_add(char* ifacename,int ifaceid, char* addr, int port, int thisifaceonly, int reuse);
299  extern int sock_del(int fd);
300  extern int sock_send(int fd, char* addr, char* buf, int buflen, int port, int iface);
301  extern int sock_recv(int fd, char* myPlainAddr, char* peerPlainAddr, char* buf, int buflen);
302 
317  extern int get_mac_from_ipv6(const char* iface_name, int ifindex, const char* v6addr,
318  char* mac, int* mac_len);
319 
320  /* pack/unpack address */
321  extern void print_packed(char addr[]);
322  extern int inet_pton6(const char* src, char* dst);
323  extern char * inet_ntop4(const char* src, char* dst);
324  extern char * inet_ntop6(const char* src, char* dst);
325  extern void print_packed(char * addr);
326  extern void doRevDnsAddress( char * src, char *dst);
327  extern void doRevDnsZoneRoot( char * src, char * dst, int lenght);
328  extern void truncatePrefixFromConfig( char * src, char * dst, char lenght);
329  extern int is_addr_tentative(char* ifacename, int iface, char* plainAddr);
330  extern void link_state_change_init(volatile struct link_state_notify_t * changed_links,
331  volatile int * notify);
332  extern void link_state_change_cleanup();
333  extern void microsleep(int microsecs);
334  extern char * error_message();
335 
336  /* options */
337  extern int dns_add(const char* ifname, int ifindex, const char* addrPlain);
338  extern int dns_del(const char* ifname, int ifindex, const char* addrPlain);
339  extern int domain_add(const char* ifname, int ifindex, const char* domain);
340  extern int domain_del(const char* ifname, int ifindex, const char* domain);
341  extern int ntp_add(const char* ifname, int ifindex, const char* addrPlain);
342  extern int ntp_del(const char* ifname, int ifindex, const char* addrPlain);
343  extern int timezone_set(const char* ifname, int ifindex, const char* timezone);
344  extern int timezone_del(const char* ifname, int ifindex, const char* timezone);
345  extern int sipserver_add(const char* ifname, int ifindex, const char* addrPlain);
346  extern int sipserver_del(const char* ifname, int ifindex, const char* addrPlain);
347  extern int sipdomain_add(const char* ifname, int ifindex, const char* domain);
348  extern int sipdomain_del(const char* ifname, int ifindex, const char* domain);
349  extern int nisserver_add(const char* ifname, int ifindex, const char* addrPlain);
350  extern int nisserver_del(const char* ifname, int ifindex, const char* addrPlain);
351  extern int nisdomain_set(const char* ifname, int ifindex, const char* domain);
352  extern int nisdomain_del(const char* ifname, int ifindex, const char* domain);
353 
354  extern int nisplusserver_add(const char* ifname, int ifindex, const char* addrPlain);
355  extern int nisplusserver_del(const char* ifname, int ifindex, const char* addrPlain);
356  extern int nisplusdomain_set(const char* ifname, int ifindex, const char* domain);
357  extern int nisplusdomain_del(const char* ifname, int ifindex, const char* domain);
358 
359  extern int prefix_add(const char* ifname, int ifindex, const char* prefixPlain, int prefixLength,
360  unsigned long prefered, unsigned long valid);
361  extern int prefix_update(const char* ifname, int ifindex, const char* prefixPlain, int prefixLength,
362  unsigned long prefered, unsigned long valid);
363  extern int prefix_del(const char* ifname, int ifindex, const char* prefixPlain, int prefixLength);
364 
365  char * getAAAKey(uint32_t SPI, uint32_t *len); /* reads AAA key from a file */
366  char * getAAAKeyFilename(uint32_t SPI); /* which file? use this function to find out */
368 
369  int execute(const char *filename, const char * argv[], const char *env[]);
370 
375  void fill_random(uint8_t* buffer, int len);
376 
383  int get_hostname(char* hostname, int hostname_len);
384 
385 #ifdef __cplusplus
386 }
387 #endif
388 
389 #ifdef LINUX
390 #ifdef DEBUG
391 void print_trace(void);
392 #endif
393 #endif
394 
395 
396 #endif
397