Tuesday, October 4
Shadow

read packets with Berkeley Packet Filter

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <net/ethernet.h>
#include <netinet/in.h>
#include <netinet/ip.h>

int  openBpf(void);
void closeBpf(int fd);
int  setupBpf(int fd, const char *ifname);
int  readPackets(int fd);

void printEther(const struct ether_header* ether);
void printIP(const struct ip* ip);
void printARP(const struct arphdr* arp);
 
static void printMACAddress(const char* str, const u_char* address);
static void printIPAddress(const char* str, const u_char* address);


static void
printMACAddress(const char* str, const u_char* address)
{
    printf("%s: %02x:%02x:%02x:%02x:%02x:%02x\n",
            str,
            address[0], address[1], address[2],
            address[3], address[4], address[5]);
}

  
static void
printIPAddress(const char* str, const u_char* address)
{
    printf("%s: %d.%d.%d.%d\n",
            str,
            address[0], address[1], address[2], address[3]);
}
  

int
openBpf(void)
{
    return open("/dev/bpf", O_RDWR);
}
 

void
closeBpf(int fd)
{
    close(fd);
}


int
setupBpf(int fd, const char *ifname)
{
    struct ifreq request;
    u_int tstamp;
    u_int type;
    u_int enable;
         
    strlcpy(request.ifr_name, ifname, sizeof(request.ifr_name) - 1);
    if (ioctl(fd, BIOCSETIF, &request) < 0) {
        perror("BIOCSETIF failed: ");
        return -1;
    }

    if (ioctl(fd, BIOCGDLT, &type) < 0) {
        perror("BIOCGDLT failed: ");
        return -1;
    }
    if (type != DLT_EN10MB) {
        printf("unsupported datalink type\n");
        return -1;
    }

    tstamp = BPF_T_NANOTIME;
    if (ioctl(fd, BIOCSTSTAMP, &tstamp) < 0) {
        perror("BIOCSTSTAMP faild: ");
        return -1;
    }

Leave a Reply