Last active
February 1, 2021 14:54
-
-
Save BobBurns/95f9a57f9a2c43a8e45fbb46977bcd17 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <fcntl.h> | |
#include <stdlib.h> | |
#include <sys/types.h> | |
#include <sys/time.h> | |
#include <net/bpf.h> | |
#include <net/if.h> | |
#include <sys/ioctl.h> | |
#include <sys/socket.h> | |
#include <net/ethernet.h> // ETHERTYPE_IP | |
#include <netinet/in.h> // IPPROTO_TCP | |
#include <unistd.h> | |
#include <time.h> | |
#define ETHLEN 14 | |
#define IPHLEN 40 | |
#define UDPLEN 8 | |
int | |
main (int argc, char *argv[]) | |
{ | |
printf("To capture DUID, bounce the interface connected to DHCPv6 capable endpoint\n"); | |
char buf[11] = { 0 }; | |
int bpf = 0; | |
for( int i = 0; i < 99; i++ ) | |
{ | |
sprintf( buf, "/dev/bpf%i", i ); | |
bpf = open( buf, O_RDWR ); | |
if( bpf != -1 ) | |
break; | |
} | |
const char * interface = "en0"; | |
struct ifreq net_if; | |
bcopy (interface, net_if.ifr_name, sizeof(interface)); | |
if (ioctl (bpf, BIOCSETIF, &net_if) == -1 ) | |
{ | |
perror("ioctl"); | |
exit(EXIT_FAILURE); | |
} | |
if (ioctl (bpf, BIOCPROMISC) < 0 ) | |
{ | |
perror("promisc"); | |
exit(EXIT_FAILURE); | |
} | |
/**************************** filter machine program ************************/ | |
struct bpf_insn bf_insns[] = { | |
BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), // ethertype | |
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x86dd, 0, 15), // ipv6 type | |
BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, ETHLEN), // | |
BPF_STMT(BPF_LD+BPF_B+BPF_IND, 6), // Next header | |
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x11, 0, 12), // UDP 17 | |
BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, ETHLEN+IPHLEN), // begin UDP header | |
BPF_STMT(BPF_LD+BPF_H+BPF_IND, 2), // dest port | |
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 547, 0, 9), // DHCPV6 | |
BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, ETHLEN+IPHLEN+UDPLEN), // begin UDP header | |
BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0), // DHCPv6 message type | |
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 3, 0, 6), // DHCPV6 message type request | |
BPF_STMT(BPF_LD+BPF_H+BPF_IND, 4), // DHCPv6 Option | |
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 1, 0, 4), // DHCPV6 option client Identifier | |
BPF_STMT(BPF_LD+BPF_H+BPF_IND, 6), // DHCPv6 CID len | |
BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), | |
BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 8), // add offset | |
BPF_STMT(BPF_RET+BPF_A, -1), // return all bytes up to DUID | |
BPF_STMT(BPF_RET+BPF_K, 0), // drop | |
}; | |
/************************ end filter machine program ***************************/ | |
struct bpf_program bprog = { | |
sizeof(bf_insns) / sizeof(struct bpf_insn), | |
bf_insns | |
}; | |
if (ioctl (bpf, BIOCSETFNR, &bprog) < 0 ) | |
{ | |
perror("BIOCSETFNR"); | |
exit(EXIT_FAILURE); | |
} | |
int buf_len = 1; | |
// activate immediate mode (therefore, buf_len is initially set to "1") | |
if( ioctl( bpf, BIOCIMMEDIATE, &buf_len ) == -1 ) { | |
perror("BIOCIMMEDIATE"); | |
exit(EXIT_FAILURE); | |
} | |
// request buffer length | |
if( ioctl( bpf, BIOCGBLEN, &buf_len ) == -1 ) { | |
perror("BIOCGBLEN"); | |
exit(EXIT_FAILURE); | |
} | |
int read_bytes = 0; | |
// struct bpf_hdr* bpf_buf = calloc(buf_len, sizeof(struct bpf_hdr)); | |
int i; | |
struct bpf_hdr* bhdr; | |
unsigned char* bpf_buf = malloc(buf_len); | |
#ifdef __APPLE__ | |
struct timeval32 tsmp; | |
#else | |
struct timeval tsmp; | |
#endif | |
char *t; | |
for (;;) { | |
if (( read_bytes = read (bpf, bpf_buf, buf_len)) > 0) | |
{ | |
bhdr = (struct bpf_hdr *)bpf_buf; | |
tsmp = bhdr->bh_tstamp; | |
t = ctime(&tsmp.tv_sec); | |
printf("time of packet:%s\n", t); | |
bpf_buf += bhdr->bh_hdrlen; | |
// assuming type 1 | |
if (bpf_buf[(bhdr->bh_caplen)-15] != 0x0e) { | |
printf("Sorry not type 1 DUID. Exiting..."); | |
break; | |
} | |
printf("DUID (first 3 bytes are length and type)\n"); | |
printf("--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n"); | |
for (i = (bhdr->bh_caplen-15); i < bhdr->bh_caplen; i++) { | |
printf("%02X ", bpf_buf[i]); | |
} | |
printf("\nend\n"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment