version 1.1, 2012/02/21 16:49:51
|
version 1.1.1.1.2.1, 2013/07/22 01:01:52
|
Line 42
|
Line 42
|
#include <string.h> |
#include <string.h> |
#include <sys/types.h> |
#include <sys/types.h> |
#include <fcntl.h> |
#include <fcntl.h> |
#include <sys/event.h> |
|
#include <sys/time.h> |
#include <sys/time.h> |
#include <sys/ioctl.h> |
#include <sys/ioctl.h> |
#include <net/bpf.h> |
#include <net/bpf.h> |
Line 76 struct cidr {
|
Line 75 struct cidr {
|
|
|
struct cidr *targets = NULL, *excludes = NULL; |
struct cidr *targets = NULL, *excludes = NULL; |
u_char target_mac[ETHER_ADDR_LEN]; /* target MAC address */ |
u_char target_mac[ETHER_ADDR_LEN]; /* target MAC address */ |
int verbose = 0; |
|
|
|
/* |
/* |
ARP filter program |
ARP filter program |
Line 241 checkarp(char *arpbuf){
|
Line 239 checkarp(char *arpbuf){
|
fprintf(stderr,"checkarp: WARNING: received unknown type ARP request.\n"); |
fprintf(stderr,"checkarp: WARNING: received unknown type ARP request.\n"); |
return(0); |
return(0); |
} |
} |
if (ntohl(*(u_int32_t *)(arp->arp_tpa)) == ntohl(*(u_int32_t *)(arp->arp_spa))) { |
|
if (verbose != 0) |
|
fprintf(stderr,"checkarp: WARNING: sender equal dest.\n"); |
|
return(0); |
|
} |
|
if (0 == ntohl(*(u_int32_t *)(arp->arp_spa))) { |
|
if (verbose != 0) |
|
fprintf(stderr,"checkarp: WARNING: zero sender address.\n"); |
|
return(0); |
|
} |
|
target_ip = ntohl(*(u_int32_t *)(arp->arp_tpa)); |
target_ip = ntohl(*(u_int32_t *)(arp->arp_tpa)); |
return match(target_ip, targets) && !match(target_ip, excludes); |
return match(target_ip, targets) && !match(target_ip, excludes); |
} |
} |
Line 292 loop(int fd, char *buf, size_t buflen){
|
Line 280 loop(int fd, char *buf, size_t buflen){
|
char *rframe; |
char *rframe; |
char *sframe; |
char *sframe; |
size_t frame_len; |
size_t frame_len; |
int kq; | fd_set fdset; |
struct kevent kev; | |
|
|
if ((kq = kqueue()) < 0) { | FD_ZERO(&fdset); |
perror("kqueue"); | FD_SET(fd,&fdset); |
return; | |
} | |
|
|
EV_SET(&kev, fd, EVFILT_READ, EV_ADD, 0, 0, NULL); |
|
if (kevent(kq, &kev, 1, NULL, 0, NULL) < 0 ) { |
|
perror("kevent"); |
|
return; |
|
} |
|
|
|
for(;;){ |
for(;;){ |
int r = kevent(kq, NULL, 0, &kev, 1, NULL); | int r = select(fd+1,&fdset, 0, 0, 0); |
|
|
if (r < 0) { |
if (r < 0) { |
if (errno == EINTR) |
if (errno == EINTR) |
Line 316 loop(int fd, char *buf, size_t buflen){
|
Line 295 loop(int fd, char *buf, size_t buflen){
|
return; |
return; |
} |
} |
|
|
rlen = read(kev.ident, buf, buflen); | rlen = read(fd, buf, buflen); |
if (rlen < 0) { |
if (rlen < 0) { |
if (errno == EINTR) |
if (errno == EINTR) |
continue; |
continue; |
Line 328 loop(int fd, char *buf, size_t buflen){
|
Line 307 loop(int fd, char *buf, size_t buflen){
|
while((rframe = getarp(p, rlen, &nextp, &nextlen)) != NULL){ |
while((rframe = getarp(p, rlen, &nextp, &nextlen)) != NULL){ |
if (checkarp(rframe)){ |
if (checkarp(rframe)){ |
sframe = gen_arpreply(rframe, &frame_len); |
sframe = gen_arpreply(rframe, &frame_len); |
write(kev.ident, sframe, frame_len); | write(fd, sframe, frame_len); |
} |
} |
p = nextp; |
p = nextp; |
rlen = nextlen; |
rlen = nextlen; |
Line 383 atoip(char *buf, u_int32_t *ip_addr){
|
Line 362 atoip(char *buf, u_int32_t *ip_addr){
|
|
|
void |
void |
usage(void){ |
usage(void){ |
fprintf(stderr,"usage: choparp [-v] if_name mac_addr [-]addr/mask...\n"); | fprintf(stderr,"usage: choparp if_name mac_addr [-]addr/mask...\n"); |
exit(-1); |
exit(-1); |
} |
} |
|
|
int |
int |
main(int argc, char **argv){ |
main(int argc, char **argv){ |
int ch, fd; | int fd; |
char *buf, *ifname; |
char *buf, *ifname; |
struct cidr **targets_tail = &targets, **excludes_tail = &excludes; |
struct cidr **targets_tail = &targets, **excludes_tail = &excludes; |
#define APPEND(LIST,ADDR,MASK) \ |
#define APPEND(LIST,ADDR,MASK) \ |
Line 402 main(int argc, char **argv){
|
Line 381 main(int argc, char **argv){
|
} while (0) |
} while (0) |
size_t buflen; |
size_t buflen; |
|
|
while ((ch = getopt(argc, argv, "v")) != -1) | if (argc < 4) |
switch (ch) { | |
case 'v': | |
verbose++; | |
break; | |
default: | |
usage(); | |
} | |
argc -= optind; | |
argv += optind; | |
| |
if (argc < 3) | |
usage(); |
usage(); |
|
|
ifname = argv[0]; | ifname = argv[1]; |
if (setmac(argv[1], ifname)) | if (setmac(argv[2], ifname)) |
usage(); |
usage(); |
argv += 2; argc -= 2; | argv += 3; argc -= 3; |
|
|
while (argc > 0) { |
while (argc > 0) { |
u_int32_t addr, mask = ~0; |
u_int32_t addr, mask = ~0; |
Line 469 main(int argc, char **argv){
|
Line 437 main(int argc, char **argv){
|
#endif |
#endif |
if ((fd = openbpf(ifname, &buf, &buflen)) < 0) |
if ((fd = openbpf(ifname, &buf, &buflen)) < 0) |
return(-1); |
return(-1); |
#ifndef DEBUG |
|
daemon(0, 0); |
|
#endif |
|
loop(fd, buf, buflen); |
loop(fd, buf, buflen); |
return(-1); |
return(-1); |
} |
} |