?? device-bsd44.c
字號:
/*
* $Id: device-bsd44.c,v 1.2 2009/08/09 23:36:05 sdhsdh Exp $
*
* Authors:
* Craig Metz <cmetz@inner.net>
*
* This software is Copyright 1996,1997 by the above mentioned author(s),
* All Rights Reserved.
*
* The license which is distributed with this software in the file COPYRIGHT
* applies to this software. If your distribution is missing this file, you
* may request it from <pekkas@netcore.fi>.
*
*/
#include <config.h>
#include <includes.h>
#include <radvd.h>
#include <defaults.h>
#include <pathnames.h> /* for PATH_PROC_NET_IF_INET6 */
static uint8_t ll_prefix[] = { 0xfe, 0x80 };
/*
* this function gets the hardware type and address of an interface,
* determines the link layer token length and checks it against
* the defined prefixes
*/
int
setup_deviceinfo(int sock, struct Interface *iface)
{
struct ifconf ifconf;
struct ifreq ifr;
unsigned int nlen;
uint8_t *p, *end;
struct AdvPrefix *prefix;
char zero[sizeof(iface->if_addr)];
/* just allocate 8192 bytes, should be more than enough.. */
if (!(ifconf.ifc_buf = malloc(ifconf.ifc_len = (32 << 8))))
{
flog(LOG_CRIT, "malloc failed: %s", strerror(errno));
goto ret;
}
if (ioctl(sock, SIOCGIFCONF, &ifconf) < 0)
{
flog(LOG_ERR, "ioctl(SIOCGIFCONF) failed: %s(%d)", strerror(errno), errno);
goto ret;
}
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, iface->Name, IFNAMSIZ-1);
ifr.ifr_name[IFNAMSIZ-1] = '\0';
if (ioctl(sock, SIOCGIFMTU, &ifr) < 0) {
flog(LOG_ERR, "ioctl(SIOCGIFMTU) failed for %s: %s", iface->Name, strerror(errno));
goto ret;
}
dlog(LOG_DEBUG, 3, "mtu for %s is %d", iface->Name, ifr.ifr_mtu);
iface->if_maxmtu = ifr.ifr_mtu;
p = (uint8_t *)ifconf.ifc_buf;
end = p + ifconf.ifc_len;
nlen = strlen(iface->Name);
while(p < end)
{
p += IFNAMSIZ;
if ((p + 2) >= end)
break;
if ((p + *p) >= end)
break;
if ((*(p + 1) == AF_LINK) &&
(((struct sockaddr_dl *)p)->sdl_nlen == nlen) &&
(!memcmp(iface->Name, ((struct sockaddr_dl *)p)->sdl_data, nlen)))
{
if (((struct sockaddr_dl *)p)->sdl_alen > sizeof(iface->if_addr))
{
flog(LOG_ERR, "address length %d too big for",
((struct sockaddr_dl *)p)->sdl_alen,
iface->Name);
goto ret;
}
memcpy(iface->if_hwaddr, LLADDR((struct sockaddr_dl *)p), ((struct sockaddr_dl *)p)->sdl_alen);
iface->if_hwaddr_len = ((struct sockaddr_dl *)p)->sdl_alen << 3;
switch(((struct sockaddr_dl *)p)->sdl_type) {
case IFT_ETHER:
case IFT_ISO88023:
iface->if_prefix_len = 64;
break;
case IFT_FDDI:
iface->if_prefix_len = 64;
break;
default:
iface->if_prefix_len = -1;
iface->if_maxmtu = -1;
break;
}
dlog(LOG_DEBUG, 3, "link layer token length for %s is %d", iface->Name,
iface->if_hwaddr_len);
dlog(LOG_DEBUG, 3, "prefix length for %s is %d", iface->Name,
iface->if_prefix_len);
if (iface->if_prefix_len != -1) {
memset(zero, 0, ((struct sockaddr_dl *)p)->sdl_alen);
if (!memcmp(iface->if_hwaddr, zero, ((struct sockaddr_dl *)p)->sdl_alen))
flog(LOG_WARNING, "WARNING, MAC address on %s is all zero!",
iface->Name);
}
prefix = iface->AdvPrefixList;
while (prefix)
{
if ((iface->if_prefix_len != -1) &&
(iface->if_prefix_len != prefix->PrefixLen))
{
flog(LOG_WARNING, "prefix length should be %d for %s",
iface->if_prefix_len, iface->Name);
}
prefix = prefix->next;
}
free(ifconf.ifc_buf);
return 0;
}
p += *p;
}
ret:
iface->if_maxmtu = -1;
iface->if_hwaddr_len = -1;
iface->if_prefix_len = -1;
free(ifconf.ifc_buf);
return -1;
}
int setup_linklocal_addr(int sock, struct Interface *iface)
{
struct ifconf ifconf;
unsigned int nlen;
uint8_t *p, *end;
int index = 0;
/* just allocate 8192 bytes, should be more than enough.. */
if (!(ifconf.ifc_buf = malloc(ifconf.ifc_len = (32 << 8))))
{
flog(LOG_CRIT, "malloc failed: %s", strerror(errno));
goto ret;
}
if (ioctl(sock, SIOCGIFCONF, &ifconf) < 0)
{
flog(LOG_ERR, "ioctl(SIOCGIFCONF) failed: %s(%d)", strerror(errno), errno);
goto ret;
}
p = (uint8_t *)ifconf.ifc_buf;
end = p + ifconf.ifc_len;
nlen = strlen(iface->Name);
while(p < end)
{
p += IFNAMSIZ;
if ((p + 2) >= end)
break;
if ((p + *p) >= end)
break;
if ((*(p + 1) == AF_LINK) &&
(((struct sockaddr_dl *)p)->sdl_nlen == nlen) &&
(!memcmp(iface->Name, ((struct sockaddr_dl *)p)->sdl_data, nlen)))
{
index = ((struct sockaddr_dl *)p)->sdl_index;
}
if (index && (*(p + 1) == AF_INET6))
if (!memcmp(&((struct sockaddr_in6 *)p)->sin6_addr, ll_prefix, sizeof(ll_prefix)))
{
memcpy(&iface->if_addr, &((struct sockaddr_in6 *)p)->sin6_addr, sizeof(struct in6_addr));
iface->if_index = index;
free(ifconf.ifc_buf);
return 0;
}
p += *p;
}
ret:
flog(LOG_ERR, "no linklocal address configured for %s", iface->Name);
free(ifconf.ifc_buf);
return -1;
}
int setup_allrouters_membership(int sock, struct Interface *iface)
{
return (0);
}
int check_allrouters_membership(int sock, struct Interface *iface)
{
return (0);
}
int
set_interface_linkmtu(const char *iface, uint32_t mtu)
{
dlog(LOG_DEBUG, 4, "setting LinkMTU (%u) for %s is not supported",
mtu, iface);
return -1;
}
int
set_interface_curhlim(const char *iface, uint8_t hlim)
{
dlog(LOG_DEBUG, 4, "setting CurHopLimit (%u) for %s is not supported",
hlim, iface);
return -1;
}
int
set_interface_reachtime(const char *iface, uint32_t rtime)
{
dlog(LOG_DEBUG, 4, "setting BaseReachableTime (%u) for %s is not supported",
rtime, iface);
return -1;
}
int
set_interface_retranstimer(const char *iface, uint32_t rettimer)
{
dlog(LOG_DEBUG, 4, "setting RetransTimer (%u) for %s is not supported",
rettimer, iface);
return -1;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -