BWM and static ARP optimizations
[tomato.git] / release / src / router / radvd / device-bsd44.c
blob412d8be79a5c8da2501ec079422ae999d5f2d5cf
1 /*
2 * $Id: device-bsd44.c,v 1.25 2010/12/14 11:58:21 psavola 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(int sock, struct Interface *iface)
32 struct ifaddrs *addresses, *ifa;
34 struct ifreq ifr;
35 struct AdvPrefix *prefix;
36 char zero[sizeof(iface->if_addr)];
38 memset(&ifr, 0, sizeof(ifr));
39 strncpy(ifr.ifr_name, iface->Name, IFNAMSIZ-1);
40 ifr.ifr_name[IFNAMSIZ-1] = '\0';
42 if (ioctl(sock, SIOCGIFMTU, &ifr) < 0) {
43 flog(LOG_ERR, "ioctl(SIOCGIFMTU) failed for %s: %s", iface->Name, strerror(errno));
44 goto ret;
47 dlog(LOG_DEBUG, 3, "mtu for %s is %d", iface->Name, ifr.ifr_mtu);
48 iface->if_maxmtu = ifr.ifr_mtu;
50 if (getifaddrs(&addresses) != 0)
52 flog(LOG_ERR, "getifaddrs failed: %s(%d)", strerror(errno), errno);
53 goto ret;
56 for (ifa = addresses; ifa != NULL; ifa = ifa->ifa_next)
58 if (strcmp(ifa->ifa_name, iface->Name) != 0)
59 continue;
61 if (ifa->ifa_addr == NULL)
62 continue;
64 if (ifa->ifa_addr->sa_family != AF_LINK)
65 continue;
67 struct sockaddr_dl *dl = (struct sockaddr_dl*)ifa->ifa_addr;
70 if (dl->sdl_alen > sizeof(iface->if_addr))
72 flog(LOG_ERR, "address length %d too big for",
73 dl->sdl_alen,
74 iface->Name);
75 goto ret;
78 memcpy(iface->if_hwaddr, LLADDR(dl), dl->sdl_alen);
79 iface->if_hwaddr_len = dl->sdl_alen << 3;
81 switch(dl->sdl_type) {
82 case IFT_ETHER:
83 case IFT_ISO88023:
84 iface->if_prefix_len = 64;
85 break;
86 case IFT_FDDI:
87 iface->if_prefix_len = 64;
88 break;
89 default:
90 iface->if_prefix_len = -1;
91 iface->if_maxmtu = -1;
92 break;
95 dlog(LOG_DEBUG, 3, "link layer token length for %s is %d", iface->Name,
96 iface->if_hwaddr_len);
98 dlog(LOG_DEBUG, 3, "prefix length for %s is %d", iface->Name,
99 iface->if_prefix_len);
101 if (iface->if_prefix_len != -1) {
102 memset(zero, 0, dl->sdl_alen);
103 if (!memcmp(iface->if_hwaddr, zero, dl->sdl_alen))
104 flog(LOG_WARNING, "WARNING, MAC address on %s is all zero!",
105 iface->Name);
108 prefix = iface->AdvPrefixList;
109 while (prefix)
111 if ((iface->if_prefix_len != -1) &&
112 (iface->if_prefix_len != prefix->PrefixLen))
114 flog(LOG_WARNING, "prefix length should be %d for %s",
115 iface->if_prefix_len, iface->Name);
118 prefix = prefix->next;
121 freeifaddrs(addresses);
122 return 0;
126 ret:
127 iface->if_maxmtu = -1;
128 iface->if_hwaddr_len = -1;
129 iface->if_prefix_len = -1;
130 freeifaddrs(addresses);
131 return -1;
135 * Saves the first link local address seen on the specified interface to iface->if_addr
138 int setup_linklocal_addr(int sock, struct Interface *iface)
140 struct ifaddrs *addresses, *ifa;
142 if (getifaddrs(&addresses) != 0)
144 flog(LOG_ERR, "getifaddrs failed: %s(%d)", strerror(errno), errno);
145 goto ret;
148 for (ifa = addresses; ifa != NULL; ifa = ifa->ifa_next)
150 if (strcmp(ifa->ifa_name, iface->Name) != 0)
151 continue;
153 if (ifa->ifa_addr == NULL)
154 continue;
156 if (ifa->ifa_addr->sa_family == AF_LINK) {
157 struct sockaddr_dl *dl = (struct sockaddr_dl*)ifa->ifa_addr;
158 if (memcmp(iface->Name, dl->sdl_data, dl->sdl_nlen) == 0)
159 iface->if_index = dl->sdl_index;
160 continue;
163 if (ifa->ifa_addr->sa_family != AF_INET6)
164 continue;
166 struct sockaddr_in6 *a6 = (struct sockaddr_in6*)ifa->ifa_addr;
168 /* Skip if it is not a linklocal address */
169 if (memcmp(&(a6->sin6_addr), ll_prefix, sizeof(ll_prefix)) != 0)
170 continue;
172 memcpy(&iface->if_addr, &(a6->sin6_addr), sizeof(struct in6_addr));
173 freeifaddrs(addresses);
174 return 0;
176 freeifaddrs(addresses);
178 ret:
179 flog(LOG_ERR, "no linklocal address configured for %s", iface->Name);
180 return -1;
183 int setup_allrouters_membership(int sock, struct Interface *iface)
185 return (0);
188 int check_allrouters_membership(int sock, struct Interface *iface)
190 return (0);
194 set_interface_linkmtu(const char *iface, uint32_t mtu)
196 dlog(LOG_DEBUG, 4, "setting LinkMTU (%u) for %s is not supported",
197 mtu, iface);
198 return -1;
202 set_interface_curhlim(const char *iface, uint8_t hlim)
204 dlog(LOG_DEBUG, 4, "setting CurHopLimit (%u) for %s is not supported",
205 hlim, iface);
206 return -1;
210 set_interface_reachtime(const char *iface, uint32_t rtime)
212 dlog(LOG_DEBUG, 4, "setting BaseReachableTime (%u) for %s is not supported",
213 rtime, iface);
214 return -1;
218 set_interface_retranstimer(const char *iface, uint32_t rettimer)
220 dlog(LOG_DEBUG, 4, "setting RetransTimer (%u) for %s is not supported",
221 rettimer, iface);
222 return -1;