1 /*
2  *
3  *   Authors:
4  *    Pedro Roque		<roque@di.fc.ul.pt>
5  *    Lars Fenneberg		<lf@elemental.net>
6  *
7  *   This software is Copyright 1996,1997 by the above mentioned author(s),
8  *   All Rights Reserved.
9  *
10  *   The license which is distributed with this software in the file COPYRIGHT
11  *   applies to this software. If your distribution is missing this file, you
12  *   may request it from <reubenhwk@gmail.com>.
13  *
14  */
15 
16 #pragma once
17 
18 #include "config.h"
19 #include "defaults.h"
20 #include "includes.h"
21 #include "log.h"
22 
23 #define CONTACT_EMAIL "Reuben Hawkins <reubenhwk@gmail.com>"
24 
25 extern int sock;
26 
27 extern int disableigmp6check;
28 
29 #define min(a, b) (((a) < (b)) ? (a) : (b))
30 
31 struct AdvPrefix;
32 struct Clients;
33 
34 #define HWADDR_MAX 16
35 #define USER_HZ 100
36 
37 struct safe_buffer {
38 	int should_free;
39 	size_t allocated;
40 	size_t used;
41 	unsigned char *buffer;
42 };
43 
44 #define SAFE_BUFFER_INIT                                                                                                         \
45 	(struct safe_buffer) { .should_free = 0, .allocated = 0, .used = 0, .buffer = 0 }
46 
47 struct safe_buffer_list {
48 	struct safe_buffer *sb;
49 	struct safe_buffer_list *next;
50 };
51 
52 struct Interface {
53 	struct Interface *next;
54 
55 	int IgnoreIfMissing;
56 	int AdvSendAdvert;
57 	double MaxRtrAdvInterval;
58 	double MinRtrAdvInterval;
59 	double MinDelayBetweenRAs;
60 	int AdvSourceLLAddress;
61 	int UnicastOnly;
62 	int AdvRASolicitedUnicast;
63 	struct Clients *ClientList;
64 
65 	struct state_info {
66 		int ready;   /* Info whether this interface has been initialized successfully */
67 		int changed; /* Info whether this interface's settings have changed */
68 		int cease_adv;
69 		uint32_t racount;
70 	} state_info;
71 
72 	struct properties {
73 		char name[IFNAMSIZ]; /* interface name */
74 		unsigned int if_index;
75 		struct in6_addr if_addr;   /* the first link local addr */
76 		struct in6_addr *if_addrs; /* all the addrs */
77 		int addrs_count;
78 		struct in6_addr *if_addr_rasrc; /* selected AdvRASrcAddress or NULL */
79 		uint32_t max_ra_option_size;
80 	} props;
81 
82 	struct ra_header_info {
83 		int AdvManagedFlag;
84 		int AdvOtherConfigFlag;
85 		uint8_t AdvCurHopLimit;
86 		int AdvHomeAgentFlag;
87 		int32_t AdvDefaultLifetime; /* XXX: really uint16_t but we need to use -1 */
88 		int AdvDefaultPreference;
89 		uint32_t AdvReachableTime;
90 		uint32_t AdvRetransTimer;
91 	} ra_header_info;
92 
93 	struct times {
94 		struct timespec last_multicast;
95 		struct timespec next_multicast;
96 		struct timespec last_ra_time;
97 	} times;
98 
99 	struct AdvPrefix *AdvPrefixList;
100 	struct AdvRoute *AdvRouteList;
101 	struct AdvRDNSS *AdvRDNSSList;
102 	struct AdvDNSSL *AdvDNSSLList;
103 
104 	uint32_t AdvLinkMTU; /* XXX: sllao also has an if_maxmtu value...Why? */
105 	uint32_t AdvRAMTU;   /* MTU used for RA */
106 
107 	struct sllao {
108 		uint8_t if_hwaddr[HWADDR_MAX];
109 		int if_hwaddr_len;
110 		int if_prefix_len;
111 		int if_maxmtu;
112 	} sllao;
113 
114 	struct mipv6 {
115 		/* Mobile IPv6 extensions */
116 		int AdvIntervalOpt;
117 		int AdvHomeAgentInfo;
118 
119 		uint16_t HomeAgentPreference;
120 		int32_t HomeAgentLifetime; /* XXX: really uint16_t but we need to use -1 */
121 
122 		/* NEMO extensions */
123 		int AdvMobRtrSupportFlag;
124 	} mipv6;
125 
126 	struct AdvLowpanCo *AdvLowpanCoList;
127 	struct AdvAbro *AdvAbroList;
128 
129 	struct AdvRASrcAddress *AdvRASrcAddressList;
130 
131 	int lineno; /* On what line in the config file was this iface defined? */
132 };
133 
134 struct Clients {
135 	struct in6_addr Address;
136 	struct Clients *next;
137 };
138 
139 struct AdvPrefix {
140 	struct in6_addr Prefix;
141 	uint8_t PrefixLen;
142 
143 	int AdvOnLinkFlag;
144 	int AdvAutonomousFlag;
145 	uint32_t AdvValidLifetime;
146 	uint32_t AdvPreferredLifetime;
147 	int DeprecatePrefixFlag;
148 	int DecrementLifetimesFlag;
149 
150 	uint32_t curr_validlft;
151 	uint32_t curr_preferredlft;
152 
153 	/* Mobile IPv6 extensions */
154 	int AdvRouterAddr;
155 
156 	/* 6to4 etc. extensions */
157 	char if6to4[IFNAMSIZ];
158 
159 	/* Select prefixes from this interface. */
160 	char if6[IFNAMSIZ];
161 
162 	struct AdvPrefix *next;
163 };
164 
165 /* More-Specific Routes extensions */
166 
167 struct AdvRoute {
168 	struct in6_addr Prefix;
169 	uint8_t PrefixLen;
170 
171 	int AdvRoutePreference;
172 	uint32_t AdvRouteLifetime;
173 	int RemoveRouteFlag;
174 
175 	struct AdvRoute *next;
176 };
177 
178 /* Options for DNS configuration */
179 
180 struct AdvRDNSS {
181 	int AdvRDNSSNumber;
182 	uint32_t AdvRDNSSLifetime;
183 	int FlushRDNSSFlag;
184 	struct in6_addr AdvRDNSSAddr1;
185 	struct in6_addr AdvRDNSSAddr2;
186 	struct in6_addr AdvRDNSSAddr3;
187 
188 	struct AdvRDNSS *next;
189 };
190 
191 struct AdvDNSSL {
192 	uint32_t AdvDNSSLLifetime;
193 
194 	int AdvDNSSLNumber;
195 	int FlushDNSSLFlag;
196 	char **AdvDNSSLSuffixes;
197 
198 	struct AdvDNSSL *next;
199 };
200 
201 /* Options for 6lopan configuration */
202 
203 struct AdvLowpanCo {
204 	uint8_t ContextLength;
205 	uint8_t ContextCompressionFlag;
206 	uint8_t AdvContextID;
207 	uint16_t AdvLifeTime;
208 	struct in6_addr AdvContextPrefix;
209 
210 	struct AdvLowpanCo *next;
211 };
212 
213 struct AdvAbro {
214 	uint16_t Version[2];
215 	uint16_t ValidLifeTime;
216 	struct in6_addr LBRaddress;
217 
218 	struct AdvAbro *next;
219 };
220 
221 struct AdvRASrcAddress {
222 	struct in6_addr address;
223 
224 	struct AdvRASrcAddress *next;
225 };
226 
227 /* Mobile IPv6 extensions */
228 
229 struct AdvInterval {
230 	uint8_t type;
231 	uint8_t length;
232 	uint16_t reserved;
233 	uint32_t adv_ival;
234 };
235 
236 struct HomeAgentInfo {
237 	uint8_t type;
238 	uint8_t length;
239 	uint16_t flags_reserved;
240 	uint16_t preference;
241 	uint16_t lifetime;
242 };
243 
244 /* Uclibc : include/netinet/icmpv6.h - Added by Bhadram*/
245 #define ND_OPT_ARO 33
246 #define ND_OPT_6CO 34
247 #define ND_OPT_ABRO 35
248 
249 struct nd_opt_abro {
250 	uint8_t nd_opt_abro_type;
251 	uint8_t nd_opt_abro_len;
252 	uint16_t nd_opt_abro_ver_low;
253 	uint16_t nd_opt_abro_ver_high;
254 	uint16_t nd_opt_abro_valid_lifetime;
255 	struct in6_addr nd_opt_abro_6lbr_address;
256 };
257 
258 struct nd_opt_6co {
259 	uint8_t nd_opt_6co_type;
260 	uint8_t nd_opt_6co_len;
261 	uint8_t nd_opt_6co_context_len;
262 	uint8_t nd_opt_6co_res_c_cid; /* [ res=3-bits | c=1-bit | cid=4-bits ] */
263 	uint16_t nd_opt_6co_reserved;
264 	uint16_t nd_opt_6co_valid_lifetime;
265 	struct in6_addr nd_opt_6co_con_prefix;
266 }; /*Added by Bhadram */
267 
268 /* gram.y */
269 struct Interface *readin_config(char const *fname);
270 
271 /* radvd.c */
272 
273 /* timer.c */
274 int expired(struct Interface const *iface);
275 int64_t timespecdiff(struct timespec const *a, struct timespec const *b);
276 struct timespec next_timespec(double next);
277 uint64_t next_time_msec(struct Interface const *iface);
278 
279 /* device.c */
280 int check_device(int sock, struct Interface *);
281 int check_ip6_forwarding(void);
282 int check_ip6_iface_forwarding(const char *iface);
283 int get_v4addr(const char *, unsigned int *);
284 int set_interface_curhlim(const char *, uint8_t);
285 int set_interface_linkmtu(const char *, uint32_t);
286 int set_interface_reachtime(const char *, uint32_t);
287 int set_interface_retranstimer(const char *, uint32_t);
288 int setup_allrouters_membership(int sock, struct Interface *);
289 int setup_iface_addrs(struct Interface *);
290 int update_device_index(struct Interface *iface);
291 int update_device_info(int sock, struct Interface *);
292 int get_iface_addrs(char const *name, struct in6_addr *if_addr, /* the first link local addr */
293 		    struct in6_addr **if_addrs			/* all the addrs */
294 		    );
295 
296 /* interface.c */
297 int check_iface(struct Interface *);
298 int setup_iface(int sock, struct Interface *iface);
299 struct Interface *find_iface_by_index(struct Interface *iface, int index);
300 struct Interface *find_iface_by_name(struct Interface *iface, const char *name);
301 struct Interface *find_iface_by_time(struct Interface *iface_list);
302 void dnssl_init_defaults(struct AdvDNSSL *, struct Interface *);
303 void for_each_iface(struct Interface *ifaces, void (*foo)(struct Interface *iface, void *), void *data);
304 void free_ifaces(struct Interface *ifaces);
305 void iface_init_defaults(struct Interface *);
306 void prefix_init_defaults(struct AdvPrefix *);
307 void rdnss_init_defaults(struct AdvRDNSS *, struct Interface *);
308 void reschedule_iface(struct Interface *iface, double next);
309 void route_init_defaults(struct AdvRoute *, struct Interface *);
310 void touch_iface(struct Interface *iface);
311 
312 /* socket.c */
313 int open_icmpv6_socket(void);
314 
315 /* send.c */
316 int send_ra_forall(int sock, struct Interface *iface, struct in6_addr *dest);
317 
318 /* process.c */
319 void process(int sock, struct Interface *, unsigned char *, int, struct sockaddr_in6 *, struct in6_pktinfo *, int);
320 
321 /* recv.c */
322 int recv_rs_ra(int sock, unsigned char *, struct sockaddr_in6 *, struct in6_pktinfo **, int *, unsigned char *);
323 
324 /* util.c */
325 int countbits(int b);
326 int count_mask(struct sockaddr_in6 *m);
327 struct in6_addr get_prefix6(struct in6_addr const *addr, struct in6_addr const *mask);
328 char *strdupf(char const *format, ...) __attribute__((format(printf, 1, 2)));
329 double rand_between(double, double);
330 int check_dnssl_presence(struct AdvDNSSL *, const char *);
331 int check_rdnss_presence(struct AdvRDNSS *, struct in6_addr *);
332 void safe_buffer_resize(struct safe_buffer *sb, size_t new_capacity);
333 size_t safe_buffer_append(struct safe_buffer *sb, void const *m, size_t count);
334 size_t safe_buffer_pad(struct safe_buffer *sb, size_t count);
335 ssize_t readn(int fd, void *buf, size_t count);
336 ssize_t writen(int fd, const void *buf, size_t count);
337 struct safe_buffer *new_safe_buffer(void);
338 void addrtostr(struct in6_addr const *, char *, size_t);
339 void safe_buffer_free(struct safe_buffer *sb);
340 struct safe_buffer_list *new_safe_buffer_list(void);
341 void safe_buffer_list_free(struct safe_buffer_list *sbl);
342 struct safe_buffer_list *safe_buffer_list_append(struct safe_buffer_list *sbl);
343 void safe_buffer_list_to_safe_buffer(struct safe_buffer_list *sbl, struct safe_buffer *sb);
344 
345 /* privsep.c */
346 int privsep_interface_curhlim(const char *iface, uint32_t hlim);
347 int privsep_interface_linkmtu(const char *iface, uint32_t mtu);
348 int privsep_interface_reachtime(const char *iface, uint32_t rtime);
349 int privsep_interface_retranstimer(const char *iface, uint32_t rettimer);
350 void privsep_init(int);
351 void privsep_set_write_fd(int);
352 
353 /*
354  * compat hacks in case libc and kernel get out of sync:
355  *
356  * glibc 2.4 and uClibc 0.9.29 introduce IPV6_RECVPKTINFO etc. and change IPV6_PKTINFO
357  * This is only supported in Linux kernel >= 2.6.14
358  *
359  * This is only an approximation because the kernel version that libc was compiled against
360  * could be older or newer than the one being run.  But this should not be a problem --
361  * we just keep using the old kernel interface.
362  *
363  * these are placed here because they're needed in all of socket.c, recv.c and send.c
364  */
365 #ifdef __linux__
366 #if defined IPV6_RECVHOPLIMIT || defined IPV6_RECVPKTINFO
367 #include <linux/version.h>
368 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14)
369 #if defined IPV6_RECVHOPLIMIT && defined IPV6_2292HOPLIMIT
370 #undef IPV6_RECVHOPLIMIT
371 #define IPV6_RECVHOPLIMIT IPV6_2292HOPLIMIT
372 #endif
373 #if defined IPV6_RECVPKTINFO && defined IPV6_2292PKTINFO
374 #undef IPV6_RECVPKTINFO
375 #undef IPV6_PKTINFO
376 #define IPV6_RECVPKTINFO IPV6_2292PKTINFO
377 #define IPV6_PKTINFO IPV6_2292PKTINFO
378 #endif
379 #endif
380 #endif
381 #endif
382