version 1.1, 2012/02/21 22:14:23
|
version 1.1.1.4, 2023/09/27 11:11:38
|
Line 27
|
Line 27
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
*/ |
*/ |
|
|
|
#include "common.h" |
|
|
#include <sys/param.h> /* optionally get BSD define */ |
#include <sys/param.h> /* optionally get BSD define */ |
|
#if !defined(__OpenBSD__) && !defined(__FreeBSD__) |
#include <sys/timeb.h> |
#include <sys/timeb.h> |
|
#endif |
#include <sys/file.h> |
#include <sys/file.h> |
#include <sys/ioctl.h> |
#include <sys/ioctl.h> |
|
|
Line 36
|
Line 40
|
#include <sys/time.h> |
#include <sys/time.h> |
#include <net/bpf.h> |
#include <net/bpf.h> |
|
|
#if (HAVE_CONFIG_H) |
|
#include "../include/config.h" |
|
#endif |
|
#include "../include/libnet.h" |
|
#include <sys/sysctl.h> |
#include <sys/sysctl.h> |
#include <net/route.h> |
#include <net/route.h> |
#include <net/if_dl.h> |
#include <net/if_dl.h> |
|
#include <net/if_types.h> |
#include "../include/gnuc.h" |
#include "../include/gnuc.h" |
|
|
#include "../include/bpf.h" |
#include "../include/bpf.h" |
|
|
#ifdef HAVE_OS_PROTO_H |
#ifdef HAVE_OS_PROTO_H |
Line 51
|
Line 53
|
#endif |
#endif |
|
|
int |
int |
libnet_bpf_open(int8_t *err_buf) | libnet_bpf_open(char *err_buf) |
{ |
{ |
int i, fd; |
int i, fd; |
int8_t device[sizeof "/dev/bpf000"]; | char device[] = "/dev/bpf000"; |
|
|
/* |
/* |
* Go through all the minors and find one that isn't in use. |
* Go through all the minors and find one that isn't in use. |
*/ |
*/ |
for (i = 0;;i++) | for (i = 0; i < 1000; i++) |
{ |
{ |
sprintf(device, "/dev/bpf%d", i); | snprintf(device, sizeof(device), "/dev/bpf%d", i); |
|
|
fd = open(device, O_RDWR); |
fd = open(device, O_RDWR); |
if (fd == -1 && errno == EBUSY) |
if (fd == -1 && errno == EBUSY) |
Line 83 libnet_bpf_open(int8_t *err_buf)
|
Line 85 libnet_bpf_open(int8_t *err_buf)
|
|
|
if (fd == -1) |
if (fd == -1) |
{ |
{ |
snprintf(err_buf, LIBNET_ERRBUF_SIZE, "%s(): open(): (%s): %s\n", | snprintf(err_buf, LIBNET_ERRBUF_SIZE, "%s(): open(): (%s): %s", |
__func__, device, strerror(errno)); |
__func__, device, strerror(errno)); |
} |
} |
return (fd); |
return (fd); |
Line 95 libnet_open_link(libnet_t *l)
|
Line 97 libnet_open_link(libnet_t *l)
|
{ |
{ |
struct ifreq ifr; |
struct ifreq ifr; |
struct bpf_version bv; |
struct bpf_version bv; |
u_int v; | uint v; |
|
|
#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT) && !(__APPLE__) |
#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT) && !(__APPLE__) |
u_int spoof_eth_src = 1; | uint spoof_eth_src = 1; |
#endif |
#endif |
|
|
if (l == NULL) |
if (l == NULL) |
Line 108 libnet_open_link(libnet_t *l)
|
Line 110 libnet_open_link(libnet_t *l)
|
|
|
if (l->device == NULL) |
if (l->device == NULL) |
{ |
{ |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): NULL device\n", | snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): NULL device", |
__func__); |
__func__); |
goto bad; |
goto bad; |
} |
} |
|
|
l->fd = libnet_bpf_open(l->err_buf); | l->fd = libnet_bpf_open((char*)l->err_buf); |
if (l->fd == -1) |
if (l->fd == -1) |
{ |
{ |
goto bad; |
goto bad; |
Line 124 libnet_open_link(libnet_t *l)
|
Line 126 libnet_open_link(libnet_t *l)
|
*/ |
*/ |
if (ioctl(l->fd, BIOCVERSION, (caddr_t)&bv) < 0) |
if (ioctl(l->fd, BIOCVERSION, (caddr_t)&bv) < 0) |
{ |
{ |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): BIOCVERSION: %s\n", | snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): BIOCVERSION: %s", |
__func__, strerror(errno)); |
__func__, strerror(errno)); |
goto bad; |
goto bad; |
} |
} |
Line 132 libnet_open_link(libnet_t *l)
|
Line 134 libnet_open_link(libnet_t *l)
|
if (bv.bv_major != BPF_MAJOR_VERSION || bv.bv_minor < BPF_MINOR_VERSION) |
if (bv.bv_major != BPF_MAJOR_VERSION || bv.bv_minor < BPF_MINOR_VERSION) |
{ |
{ |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
"%s(): kernel bpf filter out of date\n", __func__); | "%s(): kernel bpf filter out of date", __func__); |
goto bad; |
goto bad; |
} |
} |
|
|
Line 144 libnet_open_link(libnet_t *l)
|
Line 146 libnet_open_link(libnet_t *l)
|
|
|
if (ioctl(l->fd, BIOCSETIF, (caddr_t)&ifr) == -1) |
if (ioctl(l->fd, BIOCSETIF, (caddr_t)&ifr) == -1) |
{ |
{ |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): BIOCSETIF: (%s): %s\n", | snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): BIOCSETIF: (%s): %s", |
__func__, l->device, strerror(errno)); |
__func__, l->device, strerror(errno)); |
goto bad; |
goto bad; |
} |
} |
Line 154 libnet_open_link(libnet_t *l)
|
Line 156 libnet_open_link(libnet_t *l)
|
*/ |
*/ |
if (ioctl(l->fd, BIOCGDLT, (caddr_t)&v) == -1) |
if (ioctl(l->fd, BIOCGDLT, (caddr_t)&v) == -1) |
{ |
{ |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): BIOCGDLT: %s\n", | snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): BIOCGDLT: %s", |
__func__, strerror(errno)); |
__func__, strerror(errno)); |
goto bad; |
goto bad; |
} |
} |
Line 166 libnet_open_link(libnet_t *l)
|
Line 168 libnet_open_link(libnet_t *l)
|
#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT) && !(__APPLE__) |
#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT) && !(__APPLE__) |
if (ioctl(l->fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) |
if (ioctl(l->fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) |
{ |
{ |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): BIOCSHDRCMPLT: %s\n", | snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): BIOCSHDRCMPLT: %s", |
__func__, strerror(errno)); |
__func__, strerror(errno)); |
goto bad; |
goto bad; |
} |
} |
Line 232 libnet_close_link(libnet_t *l)
|
Line 234 libnet_close_link(libnet_t *l)
|
|
|
|
|
int |
int |
libnet_write_link(libnet_t *l, u_int8_t *packet, u_int32_t size) | libnet_write_link(libnet_t *l, const uint8_t *packet, uint32_t size) |
{ |
{ |
int c; |
int c; |
|
|
Line 245 libnet_write_link(libnet_t *l, u_int8_t *packet, u_int
|
Line 247 libnet_write_link(libnet_t *l, u_int8_t *packet, u_int
|
if (c != size) |
if (c != size) |
{ |
{ |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
"%s(): %d bytes written (%s)\n", __func__, c, strerror(errno)); | "%s(): %d bytes written (%s)", __func__, c, strerror(errno)); |
} |
} |
return (c); |
return (c); |
} |
} |
Line 259 libnet_get_hwaddr(libnet_t *l)
|
Line 261 libnet_get_hwaddr(libnet_t *l)
|
int8_t *buf, *next, *end; |
int8_t *buf, *next, *end; |
struct if_msghdr *ifm; |
struct if_msghdr *ifm; |
struct sockaddr_dl *sdl; |
struct sockaddr_dl *sdl; |
struct libnet_ether_addr *ea = NULL; |
|
|
|
mib[0] = CTL_NET; |
mib[0] = CTL_NET; |
mib[1] = AF_ROUTE; |
mib[1] = AF_ROUTE; |
Line 284 libnet_get_hwaddr(libnet_t *l)
|
Line 285 libnet_get_hwaddr(libnet_t *l)
|
|
|
if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1) |
if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1) |
{ |
{ |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): sysctl(): %s\n", | snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): sysctl(): %s", |
__func__, strerror(errno)); |
__func__, strerror(errno)); |
return (NULL); |
return (NULL); |
} |
} |
Line 292 libnet_get_hwaddr(libnet_t *l)
|
Line 293 libnet_get_hwaddr(libnet_t *l)
|
buf = (int8_t *)malloc(len); |
buf = (int8_t *)malloc(len); |
if (buf == NULL) |
if (buf == NULL) |
{ |
{ |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): malloc(): %s\n", | snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): malloc(): %s", |
__func__, strerror(errno)); |
__func__, strerror(errno)); |
return (NULL); |
return (NULL); |
} |
} |
if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) |
if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) |
{ |
{ |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): sysctl(): %s\n", | snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): sysctl(): %s", |
__func__, strerror(errno)); |
__func__, strerror(errno)); |
free(buf); |
free(buf); |
return (NULL); |
return (NULL); |
Line 308 libnet_get_hwaddr(libnet_t *l)
|
Line 309 libnet_get_hwaddr(libnet_t *l)
|
for (next = buf ; next < end ; next += ifm->ifm_msglen) |
for (next = buf ; next < end ; next += ifm->ifm_msglen) |
{ |
{ |
ifm = (struct if_msghdr *)next; |
ifm = (struct if_msghdr *)next; |
|
|
|
if (ifm->ifm_version != RTM_VERSION) |
|
continue; |
|
|
if (ifm->ifm_type == RTM_IFINFO) |
if (ifm->ifm_type == RTM_IFINFO) |
{ |
{ |
sdl = (struct sockaddr_dl *)(ifm + 1); |
sdl = (struct sockaddr_dl *)(ifm + 1); |
if (strncmp(&sdl->sdl_data[0], l->device, sdl->sdl_nlen) == 0) | if (sdl->sdl_type != IFT_ETHER |
| #ifdef IFT_FASTETHER |
| && sdl->sdl_type != IFT_FASTETHER |
| #endif |
| #ifdef IFT_FASTETHERFX |
| && sdl->sdl_type != IFT_FASTETHERFX |
| #endif |
| #ifdef IFT_GIGABITETHERNET |
| && sdl->sdl_type != IFT_GIGABITETHERNET |
| #endif |
| |
| && sdl->sdl_type != IFT_L2VLAN) |
| continue; |
| if (sdl->sdl_nlen == strlen(l->device) |
| && strncmp(&sdl->sdl_data[0], l->device, sdl->sdl_nlen) == 0) |
{ |
{ |
if (!(ea = malloc(sizeof(struct libnet_ether_addr)))) | memcpy(l->link_addr.ether_addr_octet, LLADDR(sdl), ETHER_ADDR_LEN); |
{ | |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, | |
"%s(): malloc(): %s", __func__, strerror(errno)); | |
free(buf); | |
return (NULL); | |
} | |
memcpy(ea->ether_addr_octet, LLADDR(sdl), ETHER_ADDR_LEN); | |
break; |
break; |
} |
} |
} |
} |
} |
} |
free(buf); |
free(buf); |
return (ea); | if (next == end) |
| { |
| snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
| "%s(): interface %s of known type not found.", |
| __func__, l->device); |
| return NULL; |
| } |
| |
| return (&l->link_addr); |
} |
} |
|
|
| /** |
/* EOF */ | * Local Variables: |
| * indent-tabs-mode: nil |
| * c-file-style: "stroustrup" |
| * End: |
| */ |