#include "os.h"
#include "common.h"
#include "device.h"
#include "mopdef.h"
#include "pf.h"
extern struct if_info *iflist;
#ifdef DEV_NEW_CONF
void
deviceEthAddr(char *ifname, u_char *eaddr)
{
struct sockaddr_dl *sdl;
struct ifaddrs *ifap, *ifa;
if (getifaddrs(&ifap) != 0) {
syslog(LOG_ERR, "deviceEthAddr: getifaddrs: %m");
exit(1);
}
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
if (sdl->sdl_family != AF_LINK || sdl->sdl_type != IFT_ETHER ||
sdl->sdl_alen != 6)
continue;
if (!strcmp(ifa->ifa_name, ifname)) {
bcopy(LLADDR(sdl), eaddr, 6);
freeifaddrs(ifap);
return;
}
}
syslog(LOG_ERR, "deviceEthAddr: Never saw interface `%s'!", ifname);
exit(1);
}
#endif
void
deviceOpen(char *ifname, u_short proto, int trans)
{
struct if_info *p, tmp;
strncpy(tmp.if_name, ifname, sizeof(tmp.if_name) - 1);
tmp.if_name[sizeof(tmp.if_name) - 1] = 0;
tmp.iopen = pfInit;
switch (proto) {
case MOP_K_PROTO_RC:
tmp.read = mopReadRC;
tmp.fd = mopOpenRC(&tmp, trans);
break;
case MOP_K_PROTO_DL:
tmp.read = mopReadDL;
tmp.fd = mopOpenDL(&tmp, trans);
break;
default:
break;
}
if (tmp.fd != -1) {
p = malloc(sizeof(*p));
if (p == 0) {
syslog(LOG_ERR, "deviceOpen: malloc: %m");
exit(1);
}
p->next = iflist;
iflist = p;
strlcpy(p->if_name, tmp.if_name, IFNAME_SIZE);
p->iopen = tmp.iopen;
p->write = pfWrite;
p->read = tmp.read;
bzero(p->eaddr, sizeof(p->eaddr));
p->fd = tmp.fd;
#ifdef DEV_NEW_CONF
deviceEthAddr(p->if_name, &p->eaddr[0]);
#else
p->eaddr[0] = tmp.eaddr[0];
p->eaddr[1] = tmp.eaddr[1];
p->eaddr[2] = tmp.eaddr[2];
p->eaddr[3] = tmp.eaddr[3];
p->eaddr[4] = tmp.eaddr[4];
p->eaddr[5] = tmp.eaddr[5];
#endif
#ifdef LINUX2_PF
{
int s;
s = socket(AF_INET, SOCK_DGRAM, 0);
pfEthAddr(s, p->if_name, &p->eaddr[0]);
close(s);
}
#endif
}
}
void
deviceInitOne(char *ifname)
{
char interface[IFNAME_SIZE];
struct if_info *p;
int trans;
#ifdef _AIX
char dev[IFNAME_SIZE];
int unit,j;
unit = 0;
for (j = 0; j < strlen(ifname); j++) {
if (isalpha((unsigned char)ifname[j]))
dev[j] = ifname[j];
else
if (isdigit((unsigned char)ifname[j])) {
unit = unit * 10 + ifname[j] - '0';
dev[j] = '\0';
}
}
if ((strlen(dev) == 2) && (dev[0] == 'e') &&
((dev[1] == 'n') || (dev[1] == 't')))
snprintf(interface, sizeof(interface), "ent%d\0", unit);
else
snprintf(interface, sizeof(interface), "%s%d\0", dev, unit);
#else
snprintf(interface, sizeof(interface), "%s", ifname);
#endif
p = iflist;
for (p = iflist; p; p = p->next)
if (strcmp(p->if_name, interface) == 0)
return;
syslog(LOG_INFO, "Initialized %s", interface);
trans = pfTrans(interface);
#ifndef NORC
switch (trans) {
case TRANS_ETHER:
deviceOpen(interface, MOP_K_PROTO_RC, TRANS_ETHER);
break;
case TRANS_8023:
deviceOpen(interface, MOP_K_PROTO_RC, TRANS_8023);
break;
case TRANS_ETHER + TRANS_8023:
deviceOpen(interface, MOP_K_PROTO_RC, TRANS_ETHER);
deviceOpen(interface, MOP_K_PROTO_RC, TRANS_8023);
break;
case TRANS_ETHER + TRANS_8023 + TRANS_AND:
deviceOpen(interface, MOP_K_PROTO_RC, TRANS_ETHER + TRANS_8023);
break;
}
#endif
#ifndef NODL
switch (trans) {
case TRANS_ETHER:
deviceOpen(interface, MOP_K_PROTO_DL, TRANS_ETHER);
break;
case TRANS_8023:
deviceOpen(interface, MOP_K_PROTO_DL, TRANS_8023);
break;
case TRANS_ETHER + TRANS_8023:
deviceOpen(interface, MOP_K_PROTO_DL, TRANS_ETHER);
deviceOpen(interface, MOP_K_PROTO_DL, TRANS_8023);
break;
case TRANS_ETHER + TRANS_8023 + TRANS_AND:
deviceOpen(interface, MOP_K_PROTO_DL, TRANS_ETHER + TRANS_8023);
break;
}
#endif
}
void
deviceInitAll()
{
#ifdef DEV_NEW_CONF
struct sockaddr_dl *sdl;
struct ifaddrs *ifap, *ifa;
if (getifaddrs(&ifap) != 0) {
syslog(LOG_ERR, "deviceInitAll: getifaddrs: %m");
exit(1);
}
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
if (sdl->sdl_family != AF_LINK || sdl->sdl_type != IFT_ETHER ||
sdl->sdl_alen != 6)
continue;
if ((ifa->ifa_flags &
(IFF_UP | IFF_LOOPBACK | IFF_POINTOPOINT)) != IFF_UP)
continue;
deviceInitOne(ifa->ifa_name);
}
freeifaddrs(ifap);
#else
struct ifaddrs *ifap, *ifa;
if (getifaddrs(&ifap) != 0) {
syslog(LOG_ERR, "deviceInitAll: getifaddrs: %m");
exit(1);
}
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
if (
ifa->ifa_flags & IFF_LOOPBACK ||
ifa->ifa_flags & IFF_POINTOPOINT)
continue;
deviceInitOne(ifa->ifa_name);
}
freeifaddrs(ifap);
#endif
}