2 * $Id: device-bsd44.c,v 1.25 2010/12/14 11:58:21 psavola Exp $
5 * Craig Metz <cmetz@inner.net>
7 * This software is Copyright 1996,1997 by the above mentioned author(s),
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>.
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
30 setup_deviceinfo(int sock
, struct Interface
*iface
)
32 struct ifaddrs
*addresses
, *ifa
;
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
));
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
);
56 for (ifa
= addresses
; ifa
!= NULL
; ifa
= ifa
->ifa_next
)
58 if (strcmp(ifa
->ifa_name
, iface
->Name
) != 0)
61 if (ifa
->ifa_addr
== NULL
)
64 if (ifa
->ifa_addr
->sa_family
!= AF_LINK
)
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",
78 memcpy(iface
->if_hwaddr
, LLADDR(dl
), dl
->sdl_alen
);
79 iface
->if_hwaddr_len
= dl
->sdl_alen
<< 3;
81 switch(dl
->sdl_type
) {
84 iface
->if_prefix_len
= 64;
87 iface
->if_prefix_len
= 64;
90 iface
->if_prefix_len
= -1;
91 iface
->if_maxmtu
= -1;
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!",
108 prefix
= iface
->AdvPrefixList
;
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
);
127 iface
->if_maxmtu
= -1;
128 iface
->if_hwaddr_len
= -1;
129 iface
->if_prefix_len
= -1;
130 freeifaddrs(addresses
);
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
);
148 for (ifa
= addresses
; ifa
!= NULL
; ifa
= ifa
->ifa_next
)
150 if (strcmp(ifa
->ifa_name
, iface
->Name
) != 0)
153 if (ifa
->ifa_addr
== NULL
)
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
;
163 if (ifa
->ifa_addr
->sa_family
!= AF_INET6
)
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)
172 memcpy(&iface
->if_addr
, &(a6
->sin6_addr
), sizeof(struct in6_addr
));
173 freeifaddrs(addresses
);
176 freeifaddrs(addresses
);
179 flog(LOG_ERR
, "no linklocal address configured for %s", iface
->Name
);
183 int setup_allrouters_membership(int sock
, struct Interface
*iface
)
188 int check_allrouters_membership(int sock
, struct Interface
*iface
)
194 set_interface_linkmtu(const char *iface
, uint32_t mtu
)
196 dlog(LOG_DEBUG
, 4, "setting LinkMTU (%u) for %s is not supported",
202 set_interface_curhlim(const char *iface
, uint8_t hlim
)
204 dlog(LOG_DEBUG
, 4, "setting CurHopLimit (%u) for %s is not supported",
210 set_interface_reachtime(const char *iface
, uint32_t rtime
)
212 dlog(LOG_DEBUG
, 4, "setting BaseReachableTime (%u) for %s is not supported",
218 set_interface_retranstimer(const char *iface
, uint32_t rettimer
)
220 dlog(LOG_DEBUG
, 4, "setting RetransTimer (%u) for %s is not supported",