Merge branch 'tomato-ND-USBmod' into tomato-RT
[tomato.git] / release / src / router / radvd / device-bsd44.c
blobac84bebf5209beea86d37ec86a6dc2a2b6d12221
1 /*
2 * $Id: device-bsd44.c,v 1.29 2011/02/06 03:41:38 reubenhwk Exp $
4 * Authors:
5 * Craig Metz <cmetz@inner.net>
7 * This software is Copyright 1996,1997 by the above mentioned author(s),
8 * All Rights Reserved.
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>.
16 #include "config.h"
17 #include "includes.h"
18 #include "radvd.h"
19 #include "defaults.h"
20 #include "pathnames.h" /* for PATH_PROC_NET_IF_INET6 */
22 static uint8_t ll_prefix[] = { 0xfe, 0x80 };
25 * this function gets the hardware type and address of an interface,
26 * determines the link layer token length and checks it against
27 * the defined prefixes
29 int
30 setup_deviceinfo(struct Interface *iface)
32 struct ifaddrs *addresses = 0, *ifa;
34 struct ifreq ifr;
35 struct AdvPrefix *prefix;
36 char zero[sizeof(iface->if_addr)];
38 if(if_nametoindex(iface->Name) == 0){
39 flog(LOG_ERR, "%s not found: %s", iface->Name, strerror(errno));
40 goto ret;
43 memset(&ifr, 0, sizeof(ifr));
44 strncpy(ifr.ifr_name, iface->Name, IFNAMSIZ-1);
45 ifr.ifr_name[IFNAMSIZ-1] = '\0';
47 if (ioctl(sock, SIOCGIFMTU, &ifr) < 0) {
48 flog(LOG_ERR, "ioctl(SIOCGIFMTU) failed for %s: %s", iface->Name, strerror(errno));
49 goto ret;
52 dlog(LOG_DEBUG, 3, "mtu for %s is %d", iface->Name, ifr.ifr_mtu);
53 iface->if_maxmtu = ifr.ifr_mtu;
55 if (getifaddrs(&addresses) != 0)
57 flog(LOG_ERR, "getifaddrs failed: %s(%d)", strerror(errno), errno);
58 goto ret;
61 for (ifa = addresses; ifa != NULL; ifa = ifa->ifa_next)
63 if (strcmp(ifa->ifa_name, iface->Name) != 0)
64 continue;
66 if (ifa->ifa_addr == NULL)
67 continue;
69 if (ifa->ifa_addr->sa_family != AF_LINK)
70 continue;
72 struct sockaddr_dl *dl = (struct sockaddr_dl*)ifa->ifa_addr;
75 if (dl->sdl_alen > sizeof(iface->if_addr))
77 flog(LOG_ERR, "address length %d too big for",
78 dl->sdl_alen,
79 iface->Name);
80 goto ret;
83 memcpy(iface->if_hwaddr, LLADDR(dl), dl->sdl_alen);
84 iface->if_hwaddr_len = dl->sdl_alen << 3;
86 switch(dl->sdl_type) {
87 case IFT_ETHER:
88 case IFT_ISO88023:
89 iface->if_prefix_len = 64;
90 break;
91 case IFT_FDDI:
92 iface->if_prefix_len = 64;
93 break;
94 default:
95 iface->if_prefix_len = -1;
96 iface->if_maxmtu = -1;
97 break;
100 dlog(LOG_DEBUG, 3, "link layer token length for %s is %d", iface->Name,
101 iface->if_hwaddr_len);
103 dlog(LOG_DEBUG, 3, "prefix length for %s is %d", iface->Name,
104 iface->if_prefix_len);
106 if (iface->if_prefix_len != -1) {
107 memset(zero, 0, dl->sdl_alen);
108 if (!memcmp(iface->if_hwaddr, zero, dl->sdl_alen))
109 flog(LOG_WARNING, "WARNING, MAC address on %s is all zero!",
110 iface->Name);
113 prefix = iface->AdvPrefixList;
114 while (prefix)
116 if ((iface->if_prefix_len != -1) &&
117 (iface->if_prefix_len != prefix->PrefixLen))
119 flog(LOG_WARNING, "prefix length should be %d for %s",
120 iface->if_prefix_len, iface->Name);
123 prefix = prefix->next;
126 freeifaddrs(addresses);
127 return 0;
131 ret:
132 iface->if_maxmtu = -1;
133 iface->if_hwaddr_len = -1;
134 iface->if_prefix_len = -1;
135 if (addresses != 0)
136 freeifaddrs(addresses);
137 return -1;
141 * Saves the first link local address seen on the specified interface to iface->if_addr
144 int setup_linklocal_addr(struct Interface *iface)
146 struct ifaddrs *addresses = 0, *ifa;
148 if (getifaddrs(&addresses) != 0)
150 flog(LOG_ERR, "getifaddrs failed: %s(%d)", strerror(errno), errno);
151 goto ret;
154 for (ifa = addresses; ifa != NULL; ifa = ifa->ifa_next)
156 if (strcmp(ifa->ifa_name, iface->Name) != 0)
157 continue;
159 if (ifa->ifa_addr == NULL)
160 continue;
162 if (ifa->ifa_addr->sa_family == AF_LINK) {
163 struct sockaddr_dl *dl = (struct sockaddr_dl*)ifa->ifa_addr;
164 if (memcmp(iface->Name, dl->sdl_data, dl->sdl_nlen) == 0)
165 iface->if_index = dl->sdl_index;
166 continue;
169 if (ifa->ifa_addr->sa_family != AF_INET6)
170 continue;
172 struct sockaddr_in6 *a6 = (struct sockaddr_in6*)ifa->ifa_addr;
174 /* Skip if it is not a linklocal address */
175 if (memcmp(&(a6->sin6_addr), ll_prefix, sizeof(ll_prefix)) != 0)
176 continue;
178 memcpy(&iface->if_addr, &(a6->sin6_addr), sizeof(struct in6_addr));
179 freeifaddrs(addresses);
180 return 0;
183 ret:
184 if(addresses)
185 freeifaddrs(addresses);
186 flog(LOG_ERR, "no linklocal address configured for %s", iface->Name);
187 return -1;
190 int setup_allrouters_membership(struct Interface *iface)
192 return (0);
195 int check_allrouters_membership(struct Interface *iface)
197 return (0);
201 set_interface_linkmtu(const char *iface, uint32_t mtu)
203 dlog(LOG_DEBUG, 4, "setting LinkMTU (%u) for %s is not supported",
204 mtu, iface);
205 return -1;
209 set_interface_curhlim(const char *iface, uint8_t hlim)
211 dlog(LOG_DEBUG, 4, "setting CurHopLimit (%u) for %s is not supported",
212 hlim, iface);
213 return -1;
217 set_interface_reachtime(const char *iface, uint32_t rtime)
219 dlog(LOG_DEBUG, 4, "setting BaseReachableTime (%u) for %s is not supported",
220 rtime, iface);
221 return -1;
225 set_interface_retranstimer(const char *iface, uint32_t rettimer)
227 dlog(LOG_DEBUG, 4, "setting RetransTimer (%u) for %s is not supported",
228 rettimer, iface);
229 return -1;