1/*
2 *   $Id: interface.c,v 1.18 2006/08/24 11:41:39 psavola Exp $
3 *
4 *   Authors:
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 <pekkas@netcore.fi>.
13 *
14 */
15
16#include <config.h>
17#include <includes.h>
18#include <radvd.h>
19#include <defaults.h>
20
21void
22iface_init_defaults(struct Interface *iface)
23{
24	memset(iface, 0, sizeof(struct Interface));
25
26	iface->HasFailed	  = 0;
27	iface->IgnoreIfMissing	  = DFLT_IgnoreIfMissing;
28	iface->AdvSendAdvert	  = DFLT_AdvSendAdv;
29	iface->MaxRtrAdvInterval  = DFLT_MaxRtrAdvInterval;
30	iface->AdvSourceLLAddress = DFLT_AdvSourceLLAddress;
31	iface->AdvReachableTime	  = DFLT_AdvReachableTime;
32	iface->AdvRetransTimer    = DFLT_AdvRetransTimer;
33	iface->AdvLinkMTU	  = DFLT_AdvLinkMTU;
34	iface->AdvCurHopLimit	  = DFLT_AdvCurHopLimit;
35	iface->AdvIntervalOpt	  = DFLT_AdvIntervalOpt;
36	iface->AdvHomeAgentInfo	  = DFLT_AdvHomeAgentInfo;
37	iface->AdvHomeAgentFlag	  = DFLT_AdvHomeAgentFlag;
38	iface->HomeAgentPreference = DFLT_HomeAgentPreference;
39	iface->MinDelayBetweenRAs   = DFLT_MinDelayBetweenRAs;
40	iface->AdvMobRtrSupportFlag = DFLT_AdvMobRtrSupportFlag;
41
42	iface->MinRtrAdvInterval = -1;
43	iface->AdvDefaultLifetime = -1;
44	iface->AdvDefaultPreference = DFLT_AdvDefaultPreference;
45	iface->HomeAgentLifetime = -1;
46}
47
48void
49prefix_init_defaults(struct AdvPrefix *prefix)
50{
51	memset(prefix, 0, sizeof(struct AdvPrefix));
52
53	prefix->AdvOnLinkFlag = DFLT_AdvOnLinkFlag;
54	prefix->AdvAutonomousFlag = DFLT_AdvAutonomousFlag;
55	prefix->AdvRouterAddr = DFLT_AdvRouterAddr;
56	prefix->AdvValidLifetime = DFLT_AdvValidLifetime;
57	prefix->AdvPreferredLifetime = DFLT_AdvPreferredLifetime;
58	prefix->if6to4[0] = 0;
59	prefix->enabled = 1;
60}
61
62void
63route_init_defaults(struct AdvRoute *route, struct Interface *iface)
64{
65	memset(route, 0, sizeof(struct AdvRoute));
66
67	route->AdvRouteLifetime = DFLT_AdvRouteLifetime(iface);
68	route->AdvRoutePreference = DFLT_AdvRoutePreference;
69}
70
71void
72rdnss_init_defaults(struct AdvRDNSS *rdnss, struct Interface *iface)
73{
74	memset(rdnss, 0, sizeof(struct AdvRDNSS));
75
76	rdnss->AdvRDNSSPreference = DFLT_AdvRDNSSPreference;
77	rdnss->AdvRDNSSOpenFlag = DFLT_AdvRDNSSOpenFlag;
78	rdnss->AdvRDNSSLifetime = DFLT_AdvRDNSSLifetime(iface);
79	rdnss->AdvRDNSSNumber = 0;
80}
81
82int
83check_iface(struct Interface *iface)
84{
85	struct AdvPrefix *prefix;
86	struct AdvRoute *route;
87	int res = 0;
88	int MIPv6 = 0;
89
90	/* Check if we use Mobile IPv6 extensions */
91	if (iface->AdvHomeAgentFlag || iface->AdvHomeAgentInfo ||
92		iface->AdvIntervalOpt)
93	{
94		MIPv6 = 1;
95		flog(LOG_INFO, "using Mobile IPv6 extensions");
96	}
97
98	prefix = iface->AdvPrefixList;
99	while (!MIPv6 && prefix)
100	{
101		if (prefix->AdvRouterAddr)
102		{
103			MIPv6 = 1;
104		}
105		prefix = prefix->next;
106	}
107
108	if (iface->MinRtrAdvInterval < 0)
109		iface->MinRtrAdvInterval = DFLT_MinRtrAdvInterval(iface);
110
111	if ((iface->MinRtrAdvInterval < (MIPv6 ? MIN_MinRtrAdvInterval_MIPv6 : MIN_MinRtrAdvInterval)) ||
112		    (iface->MinRtrAdvInterval > MAX_MinRtrAdvInterval(iface)))
113	{
114		flog(LOG_ERR,
115			"MinRtrAdvInterval for %s (%.2f) must be at least %.2f but no more than 3/4 of MaxRtrAdvInterval (%.2f)",
116			iface->Name, iface->MinRtrAdvInterval,
117			MIPv6 ? MIN_MinRtrAdvInterval_MIPv6 : (int)MIN_MinRtrAdvInterval,
118			MAX_MinRtrAdvInterval(iface));
119		res = -1;
120	}
121
122	if ((iface->MaxRtrAdvInterval < (MIPv6 ? MIN_MaxRtrAdvInterval_MIPv6 : MIN_MaxRtrAdvInterval))
123			|| (iface->MaxRtrAdvInterval > MAX_MaxRtrAdvInterval))
124	{
125		flog(LOG_ERR,
126			"MaxRtrAdvInterval for %s (%.2f) must be between %.2f and %d",
127			iface->Name, iface->MaxRtrAdvInterval,
128			MIPv6 ? MIN_MaxRtrAdvInterval_MIPv6 : (int)MIN_MaxRtrAdvInterval,
129			MAX_MaxRtrAdvInterval);
130		res = -1;
131	}
132
133	if (iface->MinDelayBetweenRAs < (MIPv6 ? MIN_DELAY_BETWEEN_RAS_MIPv6 : MIN_DELAY_BETWEEN_RAS))
134	{
135		flog(LOG_ERR,
136			"MinDelayBetweenRAs for %s (%.2f) must be at least %.2f",
137			iface->Name, iface->MinDelayBetweenRAs,
138			MIPv6 ? MIN_DELAY_BETWEEN_RAS_MIPv6 : MIN_DELAY_BETWEEN_RAS);
139		res = -1;
140	}
141
142	if ((iface->AdvLinkMTU != 0) &&
143	   ((iface->AdvLinkMTU < MIN_AdvLinkMTU) ||
144	   (iface->if_maxmtu != -1 && (iface->AdvLinkMTU > iface->if_maxmtu))))
145	{
146		flog(LOG_ERR,  "AdvLinkMTU for %s (%u) must be zero or between %u and %u",
147		iface->Name, iface->AdvLinkMTU, MIN_AdvLinkMTU, iface->if_maxmtu);
148		res = -1;
149	}
150
151	if (iface->AdvReachableTime >  MAX_AdvReachableTime)
152	{
153		flog(LOG_ERR,
154			"AdvReachableTime for %s (%u) must not be greater than %u",
155			iface->Name, iface->AdvReachableTime, MAX_AdvReachableTime);
156		res = -1;
157	}
158
159	if (iface->AdvCurHopLimit > MAX_AdvCurHopLimit)
160	{
161		flog(LOG_ERR, "AdvCurHopLimit for %s (%u) must not be greater than %u",
162			iface->Name, iface->AdvCurHopLimit, MAX_AdvCurHopLimit);
163		res = -1;
164	}
165
166	if (iface->AdvDefaultLifetime < 0)
167		iface->AdvDefaultLifetime = DFLT_AdvDefaultLifetime(iface);
168
169	if ((iface->AdvDefaultLifetime != 0) &&
170	   ((iface->AdvDefaultLifetime > MAX_AdvDefaultLifetime) ||
171	    (iface->AdvDefaultLifetime < MIN_AdvDefaultLifetime(iface))))
172	{
173		flog(LOG_ERR,
174			"AdvDefaultLifetime for %s (%u) must be zero or between %u and %u",
175			iface->Name, iface->AdvDefaultLifetime, (int)MIN_AdvDefaultLifetime(iface),
176			MAX_AdvDefaultLifetime);
177		res = -1;
178	}
179
180	/* Mobile IPv6 ext */
181	if (iface->HomeAgentLifetime < 0)
182		iface->HomeAgentLifetime = DFLT_HomeAgentLifetime(iface);
183
184	/* Mobile IPv6 ext */
185	if (iface->AdvHomeAgentInfo)
186	{
187		if ((iface->HomeAgentLifetime > MAX_HomeAgentLifetime) ||
188			(iface->HomeAgentLifetime < MIN_HomeAgentLifetime))
189		{
190			flog(LOG_ERR,
191				"HomeAgentLifetime for %s (%u) must be between %u and %u",
192				iface->Name, iface->HomeAgentLifetime,
193				MIN_HomeAgentLifetime, MAX_HomeAgentLifetime);
194			res = -1;
195		}
196	}
197
198	/* Mobile IPv6 ext */
199	if (iface->AdvHomeAgentInfo && !(iface->AdvHomeAgentFlag))
200	{
201		flog(LOG_ERR,
202			"AdvHomeAgentFlag for %s must be set with HomeAgentInfo", iface->Name);
203		res = -1;
204	}
205	if (iface->AdvMobRtrSupportFlag && !(iface->AdvHomeAgentInfo))
206	{
207		flog(LOG_ERR,
208			"AdvHomeAgentInfo for %s must be set with AdvMobRtrSupportFlag", iface->Name);
209		res = -1;
210	}
211
212	/* XXX: need this? prefix = iface->AdvPrefixList; */
213
214	while (prefix)
215	{
216		if (prefix->PrefixLen > MAX_PrefixLen)
217		{
218			flog(LOG_ERR, "invalid prefix length (%u) for %s", prefix->PrefixLen, iface->Name);
219			res = -1;
220		}
221
222		if (prefix->AdvPreferredLifetime > prefix->AdvValidLifetime)
223		{
224			flog(LOG_ERR, "AdvValidLifetime for %s (%u) must be "
225				"greater than AdvPreferredLifetime for",
226				iface->Name, prefix->AdvValidLifetime);
227			res = -1;
228		}
229
230		prefix = prefix->next;
231	}
232
233
234	route = iface->AdvRouteList;
235
236	while(route)
237	{
238		if (route->PrefixLen > MAX_PrefixLen)
239		{
240			flog(LOG_ERR, "invalid route prefix length (%u) for %s", route->PrefixLen, iface->Name);
241			res = -1;
242		}
243
244		route = route->next;
245	}
246
247	return res;
248}
249