version 1.3, 2013/07/09 00:35:36
|
version 1.5, 2013/12/15 22:57:20
|
Line 68 io_get1stiface(char *szIface, int iflen)
|
Line 68 io_get1stiface(char *szIface, int iflen)
|
} |
} |
|
|
/* |
/* |
|
* io_getmaciface() - Get MAC address from interface name |
|
* |
|
* @csIface = interface name |
|
* @ea = ethernet address |
|
* return: -1 error, 0 ok or 1 not found |
|
*/ |
|
int |
|
io_getmaciface(const char *csIface, ether_addr_t * __restrict ea) |
|
{ |
|
struct ifaddrs *ifa, *ifp; |
|
struct sockaddr_dl *dl; |
|
int ret = 1; |
|
|
|
if (!csIface || !ea) |
|
return -1; |
|
else |
|
memset(ea, 0, sizeof(ether_addr_t)); |
|
|
|
getifaddrs(&ifa); |
|
for (ifp = ifa; ifp; ifp = ifp->ifa_next) |
|
if (!strcmp(csIface, ifp->ifa_name) && ifp->ifa_addr && |
|
ifp->ifa_addr->sa_family == AF_LINK) { |
|
dl = (struct sockaddr_dl*) ifp->ifa_addr; |
|
if ((dl->sdl_type == IFT_ETHER || dl->sdl_type == IFT_L2VLAN || |
|
dl->sdl_type == IFT_BRIDGE) && |
|
dl->sdl_alen == ETHER_ADDR_LEN) { |
|
memcpy(ea, LLADDR(dl), sizeof(ether_addr_t)); |
|
ret = 0; |
|
break; |
|
} |
|
} |
|
freeifaddrs(ifa); |
|
|
|
return ret; |
|
} |
|
|
|
/* |
* io_etherClose() - Close BPF interface |
* io_etherClose() - Close BPF interface |
* |
* |
* @eth = bpf handle |
* @eth = bpf handle |
Line 169 io_etherOpen(const char *csIface, int flags, int whdr,
|
Line 206 io_etherOpen(const char *csIface, int flags, int whdr,
|
return -1; |
return -1; |
} |
} |
|
|
|
if (csIface) |
|
strlcpy(szStr, csIface, sizeof szStr); |
|
else if (io_get1stiface(szStr, sizeof szStr) == -1) { |
|
close(eth); |
|
return -1; |
|
} |
|
|
|
n = 1; |
|
if (whdr && ioctl(eth, BIOCSHDRCMPLT, &n) == -1) { |
|
LOGERR; |
|
close(eth); |
|
return -1; |
|
} |
|
if (wdlt && ioctl(eth, BIOCSDLT, &wdlt) == -1) { |
|
LOGERR; |
|
close(eth); |
|
return -1; |
|
} |
|
if (ioctl(eth, BIOCIMMEDIATE, &n) == -1) { |
|
LOGERR; |
|
close(eth); |
|
return -1; |
|
} |
|
|
if (!zcbuf) { |
if (!zcbuf) { |
if (ioctl(eth, BIOCGBLEN, &n) == -1) { |
if (ioctl(eth, BIOCGBLEN, &n) == -1) { |
LOGERR; |
LOGERR; |
close(eth); |
close(eth); |
return -1; |
return -1; |
} else |
} else |
n = (buflen && *buflen) ? *buflen : n; | n = (buflen && *buflen) ? *buflen : getpagesize(); |
| |
if (ioctl(eth, BIOCSBLEN, &n) == -1) { |
if (ioctl(eth, BIOCSBLEN, &n) == -1) { |
LOGERR; |
LOGERR; |
close(eth); |
close(eth); |
return -1; |
return -1; |
} |
} |
if (buflen && *buflen) | if (buflen) |
*buflen = n; |
*buflen = n; |
} else { |
} else { |
#ifdef __FreeBSD__ |
#ifdef __FreeBSD__ |
Line 211 io_etherOpen(const char *csIface, int flags, int whdr,
|
Line 273 io_etherOpen(const char *csIface, int flags, int whdr,
|
#endif |
#endif |
} |
} |
|
|
if (csIface) |
|
strlcpy(szStr, csIface, sizeof szStr); |
|
else if (io_get1stiface(szStr, sizeof szStr) == -1) { |
|
io_etherClose(eth, zcbuf); |
|
return -1; |
|
} |
|
memset(&ifr, 0, sizeof ifr); |
memset(&ifr, 0, sizeof ifr); |
strlcpy(ifr.ifr_name, szStr, sizeof ifr.ifr_name); |
strlcpy(ifr.ifr_name, szStr, sizeof ifr.ifr_name); |
if (ioctl(eth, BIOCSETIF, &ifr) == -1) { |
if (ioctl(eth, BIOCSETIF, &ifr) == -1) { |
Line 225 io_etherOpen(const char *csIface, int flags, int whdr,
|
Line 281 io_etherOpen(const char *csIface, int flags, int whdr,
|
return -1; |
return -1; |
} |
} |
|
|
n = 1; |
|
if (whdr && ioctl(eth, BIOCSHDRCMPLT, &n) == -1) { |
|
LOGERR; |
|
io_etherClose(eth, zcbuf); |
|
return -1; |
|
} |
|
if (wdlt && ioctl(eth, BIOCSDLT, &wdlt) == -1) { |
|
LOGERR; |
|
io_etherClose(eth, zcbuf); |
|
return -1; |
|
} |
|
if (ioctl(eth, BIOCIMMEDIATE, &n) == -1) { |
|
LOGERR; |
|
io_etherClose(eth, zcbuf); |
|
return -1; |
|
} |
|
|
|
return eth; |
return eth; |
} |
} |
|
|
Line 337 io_etherRecv(int eth, void * __restrict buf, size_t bu
|
Line 376 io_etherRecv(int eth, void * __restrict buf, size_t bu
|
|
|
if (!zcbuf) { |
if (!zcbuf) { |
rlen = read(eth, buf, buflen); |
rlen = read(eth, buf, buflen); |
if (rlen == -1) | if (rlen == -1) { |
LOGERR; |
LOGERR; |
|
return -1; |
|
} |
} else { |
} else { |
#ifdef __FreeBSD__ |
#ifdef __FreeBSD__ |
rlen = nextZCbuf(eth, (struct bpf_zbuf*) zcbuf, buf, buflen); |
rlen = nextZCbuf(eth, (struct bpf_zbuf*) zcbuf, buf, buflen); |
Line 365 io_etherRecv(int eth, void * __restrict buf, size_t bu
|
Line 406 io_etherRecv(int eth, void * __restrict buf, size_t bu
|
|
|
memmove(buf, buf + h->bh_hdrlen, rlen); |
memmove(buf, buf + h->bh_hdrlen, rlen); |
return rlen; |
return rlen; |
|
} |
|
|
|
/* |
|
* io_etherFilter() - BPF filter routine |
|
* |
|
* @eth = bpf handle |
|
* @io = filter direction |
|
* (IO_ETHER_FILTER_PROMISC|IO_ETHER_FILTER_NOTREAD|IO_ETHER_FILTER_READ|IO_ETHER_FILTER_WRITE) |
|
* @insn = BPF filter instruction array |
|
* @insnlen = Length of BPF filter instruction array |
|
* return: -1 error or 0 ok |
|
*/ |
|
int |
|
io_etherFilter(int eth, int io, struct bpf_insn * __restrict insn, size_t insnlen) |
|
{ |
|
int ret = 0; |
|
struct bpf_program fcode = { 0 }; |
|
|
|
if (io != IO_ETHER_FILTER_PROMISC && (!insn || !insnlen)) { |
|
io_SetErr(EINVAL, "invalid arguments"); |
|
return -1; |
|
} |
|
|
|
switch (io) { |
|
case IO_ETHER_FILTER_PROMISC: /* promiscuous mode */ |
|
ret = ioctl(eth, BIOCPROMISC, NULL); |
|
break; |
|
case IO_ETHER_FILTER_NOTREAD: /* read not filter */ |
|
fcode.bf_len = insnlen / sizeof(struct bpf_insn); |
|
fcode.bf_insns = insn; |
|
ret = ioctl(eth, BIOCSETFNR, &fcode); |
|
break; |
|
case IO_ETHER_FILTER_READ: /* read filter */ |
|
fcode.bf_len = insnlen / sizeof(struct bpf_insn); |
|
fcode.bf_insns = insn; |
|
ret = ioctl(eth, BIOCSETF, &fcode); |
|
break; |
|
case IO_ETHER_FILTER_WRITE: /* write filter */ |
|
fcode.bf_len = insnlen / sizeof(struct bpf_insn); |
|
fcode.bf_insns = insn; |
|
ret = ioctl(eth, BIOCSETWF, &fcode); |
|
break; |
|
} |
|
|
|
if (ret == -1) |
|
LOGERR; |
|
return ret; |
} |
} |