DragonFlyBSD Kernel Audit
DF-0354 / bpf_sniff.c
← back to finding ↓ download raw
/* Sniff tap0 and dump first packet as hex */
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/bpf.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <err.h>

int main(int argc, char **argv) {
  const char *ifn = argc>1 ? argv[1] : "tap0";
  int n = argc>2 ? atoi(argv[2]) : 1;
  char dev[16]; int fd, i;
  for (i=0;i<16;i++){snprintf(dev,sizeof(dev),"/dev/bpf%d",i); fd=open(dev,O_RDWR); if(fd>=0||((errno)!=EBUSY))break;}
  if(fd<0)err(1,"open bpf");
  struct ifreq ifr; memset(&ifr,0,sizeof(ifr));
  strlcpy(ifr.ifr_name, ifn, sizeof(ifr.ifr_name));
  if(ioctl(fd,BIOCSETIF,&ifr)<0)err(1,"setif");
  int imm=1; ioctl(fd,BIOCIMMEDIATE,&imm);
  u_int bl=0; ioctl(fd,BIOCGBLEN,&bl);
  if(bl==0)bl=4096;
  unsigned char *buf=malloc(bl);
  int got=0;
  while(got<n){
    ssize_t r=read(fd,buf,bl);
    if(r<=0)break;
    size_t off=0;
    while(off<(size_t)r){
      struct bpf_hdr *h=(struct bpf_hdr*)(buf+off);
      unsigned char *data = buf + off + h->bh_hdrlen;
      size_t caplen = h->bh_caplen;
      printf("pkt %d: caplen=%zu\n", got+1, caplen);
      for(size_t j=0;j<caplen;j++){
        printf("%02x ", data[j]);
        if((j+1)%16==0)printf("\n");
      }
      printf("\n");
      got++;
      off += BPF_WORDALIGN(h->bh_hdrlen + h->bh_caplen);
    }
  }
  close(fd);
  return 0;
}