Skip to content

Instantly share code, notes, and snippets.

@uchan-nos
Created October 18, 2014 00:53
Show Gist options
  • Save uchan-nos/1c3b9da6c675412f1dd0 to your computer and use it in GitHub Desktop.
Save uchan-nos/1c3b9da6c675412f1dd0 to your computer and use it in GitHub Desktop.
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/ethernet.h>
using namespace std;
int OpenBPF() {
char buf[11];
for (int i = 0; i < 99; ++i) {
sprintf(buf, "/dev/bpf%d", i);
int bpf = open(buf, O_RDWR);
if (bpf != -1) {
return bpf;
}
}
return -1;
}
void PrintMAC(unsigned char* mac) {
printf("%02x", mac[0]);
for (int i = 1; i < 6; ++i) {
printf(":%02x", mac[i]);
}
}
int main() {
int bpf = OpenBPF();
if (bpf == -1) {
perror("failed to open /dev/bpf*");
exit(-1);
}
const char* network_interface = "en0";
struct ifreq bound_if;
// bound network interface to bpf
strcpy(bound_if.ifr_name, network_interface);
if (ioctl(bpf, BIOCSETIF, &bound_if) == -1) {
perror("failed to associate bpf to network interface");
exit(-1);
}
int int_true = 1;
int buf_len = 0;
// activate immediate mode (no buffer)
if (ioctl(bpf, BIOCIMMEDIATE, &int_true) == -1) {
perror("failed to activate immediate mode");
exit(-1);
}
// request buffer length
if (ioctl(bpf, BIOCGBLEN, &buf_len) == -1) {
perror("failed to get buffer length");
exit(-1);
}
vector<char> bpf_buf(buf_len);
size_t i;
struct bpf_hdr* bh = nullptr;
struct ether_header* eh = nullptr;
// capture packets
while (1) {
int n = read(bpf, bpf_buf.data(), bpf_buf.size());
if (n == -1) {
perror("failed to read");
exit(-1);
}
i = 0;
while (i < n) {
bh = reinterpret_cast<struct bpf_hdr*>(bpf_buf.data() + i);
// ethernetフレームはBPFヘッダの直後から始まる
eh = reinterpret_cast<struct ether_header*>(bpf_buf.data() + i + bh->bh_hdrlen);
// print MAC address
PrintMAC(eh->ether_shost);
printf(" -> ");
PrintMAC(eh->ether_dhost);
printf(" [type=%u]\n", eh->ether_type);
i += BPF_WORDALIGN(bh->bh_hdrlen + bh->bh_caplen);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment