#ifndef lint
static const char rcsid[] =
"$FreeBSD: src/sbin/ifconfig/af_link.c,v 1.4.6.1 2008/11/25 02:59:29 kensmith Exp $";
#endif
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ifaddrs.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/ethernet.h>
#include "ifconfig.h"
static struct ifreq link_ridreq;
static void
link_status(int s __unused, const struct ifaddrs *ifa)
{
struct sockaddr_dl *sdl = (struct sockaddr_dl *) ifa->ifa_addr;
if (sdl != NULL && sdl->sdl_alen > 0) {
#ifdef notyet
if (sdl->sdl_type == IFT_ETHER &&
sdl->sdl_alen == ETHER_ADDR_LEN)
printf("\tether %s\n",
ether_ntoa((struct ether_addr *)LLADDR(sdl)));
else {
int n = sdl->sdl_nlen > 0 ? sdl->sdl_nlen + 1 : 0;
printf("\tlladdr %s\n", link_ntoa(sdl) + n);
}
#else
char *cp = (char *)LLADDR(sdl);
int n = sdl->sdl_alen;
if (sdl->sdl_type == IFT_ETHER)
printf ("\tether ");
else
printf ("\tlladdr ");
while (--n >= 0)
printf("%02x%c",*cp++ & 0xff, n>0? ':' : ' ');
putchar('\n');
#endif
}
}
static void
link_getaddr(const char *addr, int which)
{
char *temp;
struct sockaddr_dl sdl;
struct sockaddr *sa = &link_ridreq.ifr_addr;
if (which != ADDR)
errx(1, "can't set link-level netmask or broadcast");
if ((temp = malloc(strlen(addr) + 2)) == NULL)
errx(1, "malloc failed");
temp[0] = ':';
strcpy(temp + 1, addr);
sdl.sdl_len = sizeof(sdl);
link_addr(temp, &sdl);
free(temp);
if (sdl.sdl_alen > sizeof(sa->sa_data))
errx(1, "malformed link-level address");
sa->sa_family = AF_LINK;
sa->sa_len = sdl.sdl_alen;
bcopy(LLADDR(&sdl), sa->sa_data, sdl.sdl_alen);
}
static struct afswtch af_link = {
.af_name = "link",
.af_af = AF_LINK,
.af_status = link_status,
.af_getaddr = link_getaddr,
.af_aifaddr = SIOCSIFLLADDR,
.af_addreq = &link_ridreq,
};
static struct afswtch af_ether = {
.af_name = "ether",
.af_af = AF_LINK,
.af_status = link_status,
.af_getaddr = link_getaddr,
.af_aifaddr = SIOCSIFLLADDR,
.af_addreq = &link_ridreq,
};
static struct afswtch af_lladdr = {
.af_name = "lladdr",
.af_af = AF_LINK,
.af_status = link_status,
.af_getaddr = link_getaddr,
.af_aifaddr = SIOCSIFLLADDR,
.af_addreq = &link_ridreq,
};
static __constructor void
link_ctor(void)
{
af_register(&af_link);
af_register(&af_ether);
af_register(&af_lladdr);
}