version 1.5, 2013/12/15 22:57:20
|
version 1.8, 2016/08/18 09:06:31
|
Line 12 terms:
|
Line 12 terms:
|
All of the documentation and software included in the ELWIX and AITNET |
All of the documentation and software included in the ELWIX and AITNET |
Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org> |
Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org> |
|
|
Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 | Copyright 2004 - 2016 |
by Michael Pounov <misho@elwix.org>. All rights reserved. |
by Michael Pounov <misho@elwix.org>. All rights reserved. |
|
|
Redistribution and use in source and binary forms, with or without |
Redistribution and use in source and binary forms, with or without |
Line 47 SUCH DAMAGE.
|
Line 47 SUCH DAMAGE.
|
|
|
|
|
/* |
/* |
* io_get1stiface() - Get first interface of host |
|
* |
|
* @szIface = interface string buffer |
|
* @iflen = size of interface buffer |
|
* return: -1 error or 0 ok |
|
*/ |
|
int |
|
io_get1stiface(char *szIface, int iflen) |
|
{ |
|
struct ifaddrs *ifa; |
|
|
|
if (!szIface || !iflen) |
|
return -1; |
|
|
|
getifaddrs(&ifa); |
|
strlcpy(szIface, ifa->ifa_name, iflen); |
|
freeifaddrs(ifa); |
|
return 0; |
|
} |
|
|
|
/* |
|
* 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 114 io_getmaciface(const char *csIface, ether_addr_t * __r
|
Line 56 io_getmaciface(const char *csIface, ether_addr_t * __r
|
void |
void |
io_etherClose(int eth, void **zcbuf) |
io_etherClose(int eth, void **zcbuf) |
{ |
{ |
#ifdef __FreeBSD__ | #if defined(__FreeBSD__) && defined(ZCBUF_ENABLE) |
struct bpf_zbuf *zbuf = NULL; |
struct bpf_zbuf *zbuf = NULL; |
#endif |
#endif |
|
|
if (eth > STDERR_FILENO) |
if (eth > STDERR_FILENO) |
close(eth); |
close(eth); |
|
|
|
#if defined(__FreeBSD__) && defined(ZCBUF_ENABLE) |
if (zcbuf && *zcbuf) { |
if (zcbuf && *zcbuf) { |
#ifdef __FreeBSD__ |
|
zbuf = *zcbuf; |
zbuf = *zcbuf; |
munmap(zbuf->bz_bufb, zbuf->bz_buflen); |
munmap(zbuf->bz_bufb, zbuf->bz_buflen); |
munmap(zbuf->bz_bufa, zbuf->bz_buflen); |
munmap(zbuf->bz_bufa, zbuf->bz_buflen); |
e_free(*zcbuf); |
e_free(*zcbuf); |
*zcbuf = NULL; |
*zcbuf = NULL; |
#endif |
|
} |
} |
|
#endif |
} |
} |
|
|
#ifdef __FreeBSD__ | #if defined(__FreeBSD__) && defined(ZCBUF_ENABLE) |
static inline struct bpf_zbuf * |
static inline struct bpf_zbuf * |
allocZCbuf(u_int len) |
allocZCbuf(u_int len) |
{ |
{ |
Line 172 allocZCbuf(u_int len)
|
Line 114 allocZCbuf(u_int len)
|
* @csIface = interface name |
* @csIface = interface name |
* @flags = open flags |
* @flags = open flags |
* @whdr = with complete headers |
* @whdr = with complete headers |
* @wdlt = with data link type | * @wdlt = with data link type, on Linux is protocol number |
* @buflen = buffer length |
* @buflen = buffer length |
* @zcbuf = zero copy buffer, if BPF supports it and isn't NULL |
* @zcbuf = zero copy buffer, if BPF supports it and isn't NULL |
* return: -1 error or >-1 bpf handle |
* return: -1 error or >-1 bpf handle |
*/ |
*/ |
int |
int |
io_etherOpen(const char *csIface, int flags, int whdr, int wdlt, | io_etherOpen(const char *csIface, int flags, u_int whdr, u_int wdlt, |
u_int *buflen, void **zcbuf) |
u_int *buflen, void **zcbuf) |
{ |
{ |
int eth = -1; |
int eth = -1; |
register int i; |
|
char szStr[STRSIZ]; |
char szStr[STRSIZ]; |
struct ifreq ifr; |
struct ifreq ifr; |
|
#ifndef __linux__ |
|
register int i; |
u_int n = 1; |
u_int n = 1; |
|
#else |
|
sockaddr_t sa = {{ 0 }}; |
|
#endif |
|
|
#ifndef __FreeBSD__ | #if !defined(__FreeBSD__) || !defined(ZCBUF_ENABLE) |
if (zcbuf) { |
if (zcbuf) { |
io_SetErr(ENOTSUP, "bpf zero copy buffer mode is not supported"); |
io_SetErr(ENOTSUP, "bpf zero copy buffer mode is not supported"); |
return -1; |
return -1; |
} |
} |
#endif |
#endif |
|
|
|
#ifndef __linux__ |
for (i = 0; i < BPF_DEV_MAX; i++) { |
for (i = 0; i < BPF_DEV_MAX; i++) { |
memset(szStr, 0, sizeof szStr); |
memset(szStr, 0, sizeof szStr); |
snprintf(szStr, sizeof szStr, "/dev/bpf%d", i); |
snprintf(szStr, sizeof szStr, "/dev/bpf%d", i); |
Line 201 io_etherOpen(const char *csIface, int flags, int whdr,
|
Line 148 io_etherOpen(const char *csIface, int flags, int whdr,
|
if (eth > STDERR_FILENO) |
if (eth > STDERR_FILENO) |
break; |
break; |
} |
} |
|
#else |
|
eth = socket(AF_PACKET, whdr ? SOCK_RAW : SOCK_DGRAM, htons((u_short) wdlt)); |
|
#endif |
if (eth < 3) { |
if (eth < 3) { |
LOGERR; |
LOGERR; |
return -1; |
return -1; |
Line 208 io_etherOpen(const char *csIface, int flags, int whdr,
|
Line 158 io_etherOpen(const char *csIface, int flags, int whdr,
|
|
|
if (csIface) |
if (csIface) |
strlcpy(szStr, csIface, sizeof szStr); |
strlcpy(szStr, csIface, sizeof szStr); |
else if (io_get1stiface(szStr, sizeof szStr) == -1) { | else if (e_get1stiface(szStr, sizeof szStr) == -1) { |
close(eth); |
close(eth); |
return -1; |
return -1; |
} |
} |
|
|
|
#ifndef __linux__ |
n = 1; |
n = 1; |
if (whdr && ioctl(eth, BIOCSHDRCMPLT, &n) == -1) { |
if (whdr && ioctl(eth, BIOCSHDRCMPLT, &n) == -1) { |
LOGERR; |
LOGERR; |
close(eth); |
close(eth); |
return -1; |
return -1; |
} |
} |
if (wdlt && ioctl(eth, BIOCSDLT, &wdlt) == -1) { |
|
LOGERR; |
|
close(eth); |
|
return -1; |
|
} |
|
if (ioctl(eth, BIOCIMMEDIATE, &n) == -1) { |
if (ioctl(eth, BIOCIMMEDIATE, &n) == -1) { |
LOGERR; |
LOGERR; |
close(eth); |
close(eth); |
Line 246 io_etherOpen(const char *csIface, int flags, int whdr,
|
Line 192 io_etherOpen(const char *csIface, int flags, int whdr,
|
if (buflen) |
if (buflen) |
*buflen = n; |
*buflen = n; |
} else { |
} else { |
#ifdef __FreeBSD__ | #if defined(__FreeBSD__) && defined(ZCBUF_ENABLE) |
n = BPF_BUFMODE_ZBUF; |
n = BPF_BUFMODE_ZBUF; |
if (ioctl(eth, BIOCSETBUFMODE, &n) == -1) { |
if (ioctl(eth, BIOCSETBUFMODE, &n) == -1) { |
LOGERR; |
LOGERR; |
Line 281 io_etherOpen(const char *csIface, int flags, int whdr,
|
Line 227 io_etherOpen(const char *csIface, int flags, int whdr,
|
return -1; |
return -1; |
} |
} |
|
|
|
n = wdlt; |
|
if (wdlt && ioctl(eth, BIOCSDLT, &n) == -1) { |
|
LOGERR; |
|
close(eth); |
|
return -1; |
|
} |
|
#else |
|
memset(&ifr, 0, sizeof ifr); |
|
strlcpy(ifr.ifr_name, szStr, sizeof ifr.ifr_name); |
|
if (ioctl(eth, SIOCGIFINDEX, &ifr)) { |
|
LOGERR; |
|
close(eth); |
|
return -1; |
|
} |
|
|
|
sa.sll.sll_family = AF_PACKET; |
|
sa.sll.sll_ifindex = ifr.ifr_ifindex; |
|
sa.sll.sll_protocol = htons((u_short) wdlt); |
|
if (bind(eth, &sa.sa, sizeof(sa.sll)) == -1) { |
|
LOGERR; |
|
close(eth); |
|
return -1; |
|
} |
|
#endif |
|
|
return eth; |
return eth; |
} |
} |
|
|
Line 308 io_etherSend(int eth, const void *buf, size_t buflen)
|
Line 279 io_etherSend(int eth, const void *buf, size_t buflen)
|
return wlen; |
return wlen; |
} |
} |
|
|
#ifdef __FreeBSD__ | #if defined(__FreeBSD__) && defined(ZCBUF_ENABLE) |
static inline void |
static inline void |
ackZCbuf(struct bpf_zbuf_header *bzh) |
ackZCbuf(struct bpf_zbuf_header *bzh) |
{ |
{ |
Line 367 ssize_t
|
Line 338 ssize_t
|
io_etherRecv(int eth, void * __restrict buf, size_t buflen, void * __restrict zcbuf) |
io_etherRecv(int eth, void * __restrict buf, size_t buflen, void * __restrict zcbuf) |
{ |
{ |
ssize_t rlen = 0; |
ssize_t rlen = 0; |
|
#ifndef __linux__ |
struct bpf_hdr *h; |
struct bpf_hdr *h; |
|
#endif |
|
|
if (!buf || !buflen) { |
if (!buf || !buflen) { |
io_SetErr(EINVAL, "invalid arguments"); |
io_SetErr(EINVAL, "invalid arguments"); |
Line 381 io_etherRecv(int eth, void * __restrict buf, size_t bu
|
Line 354 io_etherRecv(int eth, void * __restrict buf, size_t bu
|
return -1; |
return -1; |
} |
} |
} else { |
} else { |
#ifdef __FreeBSD__ | #if defined(__FreeBSD__) && defined(ZCBUF_ENABLE) |
rlen = nextZCbuf(eth, (struct bpf_zbuf*) zcbuf, buf, buflen); |
rlen = nextZCbuf(eth, (struct bpf_zbuf*) zcbuf, buf, buflen); |
if (!rlen) |
if (!rlen) |
rlen = nextZCbuf(eth, (struct bpf_zbuf*) zcbuf, buf, buflen); |
rlen = nextZCbuf(eth, (struct bpf_zbuf*) zcbuf, buf, buflen); |
Line 391 io_etherRecv(int eth, void * __restrict buf, size_t bu
|
Line 364 io_etherRecv(int eth, void * __restrict buf, size_t bu
|
#endif |
#endif |
} |
} |
|
|
|
#ifndef __linux__ |
h = (struct bpf_hdr*) buf; |
h = (struct bpf_hdr*) buf; |
rlen -= h->bh_hdrlen; |
rlen -= h->bh_hdrlen; |
|
|
Line 405 io_etherRecv(int eth, void * __restrict buf, size_t bu
|
Line 379 io_etherRecv(int eth, void * __restrict buf, size_t bu
|
} |
} |
|
|
memmove(buf, buf + h->bh_hdrlen, rlen); |
memmove(buf, buf + h->bh_hdrlen, rlen); |
|
#endif |
return rlen; |
return rlen; |
} |
} |
|
|
|
#ifndef __linux__ |
/* |
/* |
* io_etherFilter() - BPF filter routine |
* io_etherFilter() - BPF filter routine |
* |
* |
Line 454 io_etherFilter(int eth, int io, struct bpf_insn * __re
|
Line 430 io_etherFilter(int eth, int io, struct bpf_insn * __re
|
LOGERR; |
LOGERR; |
return ret; |
return ret; |
} |
} |
|
#endif |