Linuxã®BPF : (1) ãã±ãããã£ã«ã¿
ã¯ããã«
BPFã¯Berkeley Packet Filterã®ç¥ã§ï¼1993å¹´ã«å¹ççãªãã±ãããã£ã«ã¿ãªã³ã°ææ³ã¨ãã¦ææ¡ããã¾ãã[1]
*1ï¼
BPFã®æ§æè¦ç´ ã¯å¤§ãã2ã¤ãã£ã¦ï¼ä¸ã¤ããããã¯ã¼ã¯ãããã±ããããã£ããã£ããé¨åï¼ããã¦ããä¸ã¤ããã£ããã£ãã
ãã±ããããã£ã«ã¿ãªã³ã°ããé¨åã§ãï¼BPFã¨ãã£ãå ´åï¼å¾è
ã®ãã£ã«ã¿ãªã³ã°æ©æ§ã ããæããã¨ãå¤ãã§ãï¼
FreeBSDãªã©ã®BSDç³»ã®OSã§ã¯/dev/bpf*
ã¨ããç¹å¥ãªããã¤ã¹ããã£ã¦ï¼ãã®BPFãå©ç¨ãããã¨ãã§ãã¾ãï¼ã¾ãï¼
Linuxã§ããã±ãããã£ã«ã¿ãªã³ã°ï¼Linux Sokcet Filtering; LSFï¼ã«BPFã®ãã£ã«ã¿ãªã³ã°ããµãã¼ããã¦ãã¾ã*2ï¼
ãããªBPFã§ããï¼Linuxã§ã¯ããæ°å¹´ã§é²åãéãï¼ãã±ãããã£ã«ã¿ãªã³ã°ä»¥å¤ã®ç¨éã«ã使ãããããã«ãªãã¾ããï¼ ä¾ãã°ï¼ããã»ã¹ã®ãµã³ãããã¯ã¹åã®ããã«çºè¡ã§ããã·ã¹ãã ã³ã¼ã«ãå¶éããseccomp[2]ã¯ã·ã¹ãã ã³ã¼ã«ããã£ã«ã¿ãªã³ã°ããããã«BPFãå©ç¨ãã¦ãã¾ãï¼ããã«ï¼Linux 3.15ããkprobe[3]ã¨BPFãåããã¦å©ç¨ãããã¨ãå¯è½ã¨ãªãï¼ã«ã¼ãã«å ã§ã®æ§ã ãªã¤ãã³ãã«å¯¾ãã¦ã¦ã¼ã¶ãå®ç¾©ããå¦çããããªããã¨ãã§ãã¾ã*3ï¼ä¾ãã°ï¼ iovisorã使ãã¦ããbccã¯BPFãæ´»ç¨ãããã¤ãããã¯ãã¬ã¼ã¹ãã¼ã«ç¾¤ã§ï¼ ãã£ã¹ã¯I/Oã®ã¬ã¤ãã³ã·ã®æ¸¬å®ï¼æ°ããããã»ã¹ã®å®è¡ã®ç£è¦ï¼TCPã³ãã¯ã·ã§ã³æ å ± ã®åå¾ï¼ã¹ã¿ãã¯ãããã¡ã¤ãªã³ã°æ©è½çã ï¼ãã¾ãã¾ãªãã¨ãã§ãã¾ãï¼
BPFã¯å ã ãã±ãããã£ã«ã¿ãªã³ã°æ©æ§ã ã£ãã¯ããªã®ã«ãã£ããã©ããããã¨ããã...ã¨ãããã¨ã§Linuxã«ãããBPFã«ã¤ã㦠ããã§ã¯ãã®æ©æ§ã¨ä½æ ãã®ãããªãã¨ãå¯è½ãªã®ãã説æãããã¨æãã¾ãï¼ãã®ããã«ã¾ããªãªã¸ãã«ã®BPFã¨Linuxã§BPF ãå©ç¨ãããã£ã«ã¿ãªã³ã°ã«ã¤ãã¦èª¬æãããã¨ï¼seccompã§ã®BPFã®ä½¿ããæ¹ã説æãï¼æå¾ã«æè¿ã®BPFãå©ç¨ãããã¬ã¼ã¹ã«ã¤ãã¦èª¬æãã¾ãï¼
ã¾ãå§ãã¯BPFã§ã®ãã±ãããã£ã«ã¿ãªã³ã°ã«ã¤ãã¦è¦ã¦ããã¾ãï¼
BPFã®åºç¤
ã¾ãã¯ããã«ãªãªã¸ãã«ã®BPFè«æã«ã¤ãã¦èª¬æãã¾ãï¼
BPFã®æ§é
BPFã®æ§é ã¯ä»¥ä¸ã®ããã«ãªã£ã¦ãã¾ãï¼
(è«æããå¼ç¨)
BPFã®åºæ¬çãªä½¿ãæ¹ã¯ä»¥ä¸ã®éãã§ãï¼
- ã¦ã¼ã¶ã®ããã»ã¹ã
/dev/bpf*
ãéãï¼å³ã«ç¤ºããããã«ãããã¯ã¼ã¯ããã¤ã¹ã¨ããã»ã¹ãBPFãæãã§æ¥ç¶ãããï¼ - ã¦ã¼ã¶ããã»ã¹ã¯ããã»ã¹ãã¨ã«ãã£ã«ã¿ãªã³ã°ããã°ã©ã ï¼æ¬¡ã§èª¬æï¼ãè¨å®ããï¼
- ããã¤ã¹ããã±ãããåä¿¡ããã¨ï¼ãããBPFã®æ©æ§ã«éããï¼ãã£ã«ã¿ãªã³ã°ãããçµæããããã¡ã«ãã¾ãï¼
- ã¦ã¼ã¶ã¯ããã¤ã¹ãreadãããã¨ã§ãã±ãããåä¿¡ããï¼
ã«ã¼ãã«å ã§ãã£ã«ã¿ãªã³ã°ãããããï¼ç¡é§ãªã³ãã¼ãçºçããå¹ççã§ãï¼ ããã«ï¼ãã£ã«ã¿ãªã³ã°ææ³ã次ã«èª¬æããããã«å¹ççãªãã®ã«ãªã£ã¦ãã¾ãï¼
BPFã§ã®ãã£ã«ã¿ãªã³ã°
BPF以åã®ãã±ãããã£ã«ã¿ãªã³ã°ææ³ã¨ãã¦ï¼ä»£è¡¨çãªãã®ã«CMU/Stanford PacketFilter(CSPF)[4]ãããã¾ããï¼CSPFã§ã¯ãã£ã«ã¿ãªã³ã°ã¯è«çæ¼ç®ï¼æ¨æ§é ï¼ã§è¡¨ç¾ãã¾ãï¼ä¸æ¹BPFã§ã¯ãã£ã«ã¿ãªã³ã°ãCFGï¼Control Flow Graphï¼ã¨ãã¦è¡¨ç¾ãã¾ãï¼ä»¥ä¸ã«CSPFã¨BPFã§ã®ãã£ã«ã¿ã®è¡¨ç¾ä¾ã示ãã¾ãï¼
(è«æããå¼ç¨)
CSPFã®ãããªæ¨æ§é ã®è¡¨ç¾ã¯ä¸è¬ã«ã¹ã¿ãã¯ãã·ã³ã§è©ä¾¡ãããã¨ãã§ãã¾ãï¼ãããï¼ä¸è¬ã«ã¹ã¿ãã¯ã¯ã¡ã¢ãªä¸ã«ç½®ãããããè©ä¾¡ã®ããã«å¿ è¦ãªã¡ã¢ãªã¢ã¯ã»ã¹ãå¢ãããã¨ãï¼é度ä½ä¸ã®åå ï¼ï¼éå¹ççãªãã±ããã®ãã¼ã¹ãä½åº¦ãçºçãããªã©ã¨ãã£ãåé¡ãããã¾ããï¼ã¾ãï¼CSPFã«ã¯åºå®ãªãã»ããä½ç½®ã®è¦ç´ ã«ããã¢ã¯ã»ã¹ã§ããªãã¨ãã£ãåé¡ãããã¾ããï¼
BPFã¯ãããã®åé¡ã解決ãï¼æ±ç¨çãã¤å¹ççãªãã£ã«ã¿ãªã³ã°ããããªãããã«ï¼ä»®æ³çãªã¬ã¸ã¹ã¿ãã·ã³ãææ¡ãã¾ããï¼
ã¬ã¸ã¹ã¿ãã·ã³
BPFã§å©ç¨ããã¬ã¸ã¹ã¿ãã·ã³ã®å½ä»¤ã»ããã¯64bitåºå®ã§ï¼ãã©ã¼ãããã¯ä»¥ä¸ã®éãã§ãï¼
opcode:16 jt:8 jf:8 k:32
jt
ãåå²å½ä»¤ã«ããã¦æ¡ä»¶ãçã®ã¨ãã®åå²å
ï¼jf
ãå½ã®æã®åå²å
ã§ãï¼k
ã¯å½ä»¤ãã¨ã«ãããããç®çãå¤ããã¾ãï¼
ãã®ãã·ã³ã¯32bitã®ã¬ã¸ã¹ã¿2ã¤(Aã¨X)ã¨ä½æ¥ç¨ã®ã¡ã¢ãªããã³å¦ç対象ã®ãã±ããã®ãã¼ã¿ã«ã¢ã¯ã»ã¹ãããã¨ãå¯è½ã§ãï¼Aãã¢ãã¥ã ã¬ã¼ã¿ï¼Xã¯ã¤ã³ããã¯ã¹ã¬ã¸ã¹ã¿ã¨ãã¦å©ç¨ãã¾ãï¼ å½ä»¤ã»ãã㯠1) ã¹ãã¢ï¼2) ãã¼ãï¼3) ç®è¡æ¼ç®ï¼4) åå²ï¼5) returnï¼6) ãã®ä» ã®6種é¡22å½ä»¤ãããªãã¾ãï¼
(è«æããå¼ç¨)
ä¾ãã°ï¼ãªã³ã¯ã¬ã¤ã¤ã¼ã§Ethernetã使ã£ã¦ããããã¤ã¹ã§ARPãã±ããã®ã¿ãåçãããã£ã«ã¿ããã°ã©ã ã¯ä»¥ä¸ã®ããã«ãªãã¾ãï¼
ldh [12] // ãã±ããå é 12byteç®ãã2byteãã¼ã jne #0x806, drop // èªã¿è¾¼ãã å¤ã0x806ã§ãªããã°dropã¸ã¸ã£ã³ã ret #-1 drop: ret #0
ã¤ã¼ãµããããã¬ã¼ã ã¯preambleãé¤ãã¨å é ãã12byteãã2byteãtype/lengthãã£ã¼ã«ãã§ï¼ãã®å¤ã0x806ã®ã¨ããã±ãããARPã§ãããã¨ã示ãã¾ã[5]ï¼æ»ãå¤ã0ã®å ´åãã®ãã±ããã¯æ£å´ããã¾ãï¼
BPFã§ãã£ã«ã¿ãªã³ã°ããéã¯ï¼ãã®ããã«ã¦ã¼ã¶ãBPFã®ããã°ã©ã ã使ãè¨å®ããããã§ããï¼BPFã®ããã°ã©ã ã¯ã«ã¼ãã«å ã§å®è¡ ãããããï¼ããã°ã©ã ã¯å®å ¨ã§ããå¿ è¦ãããã¾ãï¼ããã§ï¼ å®å ¨æ§ç¢ºä¿ã®ããã«ä¾ãã°è² ã®æ¹åã«å¯¾ããã¸ã£ã³ãã¯ç¦æ¢ããã¦ãã¾ãï¼ç¡éã«ã¼ãã鲿¢ããããï¼ï¼ã«ã¼ãã«ã«ã¯BPFããã°ã©ã ãå®è¡ãã¦å®å ¨ãã©ãããäºåã«éçã«è§£æãã¦æ¤è¨¼ããæ©è½ãå ¥ã£ã¦ãã¾ãï¼
以ä¸ï¼BPFã¨ãã£ãå ´åBPFã®ãã£ã«ã¿ãªã³ã°æ©æ§ã«ã¤ãã¦æããã¨ã«ãã¾ãï¼
Linuxã§ã®BPF
Linuxã«ã¯/dev/bpf*
ã¯åå¨ããï¼
Linuxã§ãã±ãããã£ããã£ãããå ´åã¯ã½ã±ããã®ãããã³ã«ãã¡ããªã«PF_PACKET
ãæå®ãããã¨ã§ãããªãã¾ãã[6]ï¼
ã«ã¼ãã«å
ã§ãã±ããã®ãã£ã«ã¿ãªã³ã°ããããã«Linux Socket Filtering (LSF) ã¨ããä»çµã¿ãç¨æããã¦ãã¾ã[7]ï¼
ãã®LSFã®ãã£ã«ã¿ãªã³ã°ã¢ã«ã´ãªãºã ã¯å®ã¯BPFï¼ãæ¡å¼µãããã®ï¼ã§ãï¼
Linuxã®BPFã«é¢ãã¦ã¯ã«ã¼ãã«ã®ããã¥ã¡ã³ã Documentation/networking/filter.txt [7]ã«ã¾ã¨ã¾ã£ã¦ãã¾ãã®ã§ï¼ ä¸èªãå§ãã¾ãï¼ ã¾ãBPFããã°ã©ã ã®ä»æ§ã¯BSDã®ãã®ãå¼ãç¶ãã§ããã®ã§ï¼FreeBSDã®bpf(4)ã®manãã¼ã¸[8]ãåèã«ãªãã¾ãï¼
BPFãå©ç¨ãããã±ãããã£ã«ã¿ãªã³ã°
Linuxã§LSFï¼BPFï¼ãå©ç¨ãããã±ãããã£ã«ã¿ãªã³ã°ã®ä¾ãè¦ã¦ã¿ã¾ãããï¼ä»¥ä¸ã®ããã°ã©ã ã¯ãã±ããããã£ããã£ãã¦ããã IPãã±ãããARPãã±ããããã以å¤ããåºåããã ãã®ããã°ã©ã ã§ã*4ï¼
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <arpa/inet.h> #include <linux/if_ether.h> #include <linux/filter.h> #include <netpacket/packet.h> #include <net/if.h> int main(){ int soc; struct ifreq ifr; struct sockaddr_ll sll; unsigned char buf[4096]; memset(&ifr, 0, sizeof(ifr)); memset(&sll, 0, sizeof(sll)); soc = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); strncpy(ifr.ifr_name, "br0", IFNAMSIZ); ioctl(soc, SIOCGIFINDEX, &ifr); sll.sll_family = AF_PACKET; sll.sll_protocol = htons(ETH_P_ALL); sll.sll_ifindex = ifr.ifr_ifindex; bind(soc, (struct sockaddr *)&sll, sizeof(sll)); while(1){ ssize_t len = recv(soc, buf, sizeof(buf), 0); struct ethhdr* ethhdr = (struct ethhdr*)buf; int proto = ntohs(ethhdr->h_proto); if(len <= 0) break; printf("%3ld %0x %s\n", len, proto, proto==ETH_P_ARP ? "arp" : proto==ETH_P_IP ? "ip" : "other"); } return 0; }
ããã§ï¼BPFããã°ã©ã ã使ã£ã¦ARPãã±ããã®ã¿ãåçããããã«ãã¦ã¿ã¾ãããï¼ãã®ããã«ã¯ï¼setsockopt(2)
ã·ã¹ãã ã³ã¼ã«[8]ã
以ä¸ã®ããã«å©ç¨ãã¦ï¼ã½ã±ããã®fdã«å¯¾ãã¦BPFããã°ã©ã ãã¢ã¿ãããã¾ãï¼
setsockopt(sockfd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf));
ããã§ï¼bpf
ã¯<linux/filter.h>
ã®ä¸ã§å®ç¾©ããã¦ããsock_fprog
æ§é ä½ã§ãï¼
struct sock_fprog { /* Required for SO_ATTACH_FILTER. */ unsigned short len; /* Number of filter blocks */ struct sock_filter *filter; }; struct sock_filter { /* Filter block */ __u16 code; /* Actual filter code */ __u8 jt; /* Jump true */ __u8 jf; /* Jump false */ __u32 k; /* Generic multiuse field */ };
ãã®ããã«ï¼BPFããã°ã©ã ã®å®ä½ã¯sock_filter
æ§é ä½ã®é
åã§ãï¼
BPFå½ä»¤ã®ã³ã¼ãã¯<linux/bpf_common.h>
ã§defineããã¦ãã¾ãï¼
ã¾ãï¼BPFå½ä»¤åã¯ãã¯ãã使ã£ã¦å®ç¾©ãããã¨ãã§ãã¾ãï¼ãã¡ãããã³ãã¢ã»ã³ãã«ããã人ã¯ããã°ããã§ãã..ï¼ï¼
struct sock_filter code[] = { BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 12), // ldh [12] BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x806, 0, 1), // jeq #0x806 jt 0 jf 1 BPF_STMT(BPF_RET | BPF_K, -1), // ret #-1 BPF_STMT(BPF_RET | BPF_K, 0) // ret #0 }; struct sock_fprog bpf = { .len = sizeof(code)/sizeof(code[0]), .filter = code, };
ãã¯ãã«ã¤ãã¦ã¯åè¿°ã®ããã¥ã¡ã³ã[7]ï¼[8]ã«è©³ããã¯æ¸ãã¦ããã¾ãï¼
以ä¸ãã¾ã¨ããã¨ï¼ãã£ã«ã¿ãªã³ã°ããã°ã©ã å ¨ä½ã¯ä»¥ä¸ã®ããã«ãªãã¾ãï¼
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <arpa/inet.h> #include <linux/if_ether.h> #include <linux/filter.h> #include <linux/kernel.h> #include <netpacket/packet.h> #include <net/if.h> struct sock_filter code[] = { BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 12), // ldh [12] BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x806, 0, 1), // jeq #0x06 jt 2 jf 3 BPF_STMT(BPF_RET | BPF_K, -1), // ret #-1 BPF_STMT(BPF_RET | BPF_K, 0) // ret #0 }; struct sock_fprog bpf = { .len = sizeof(code)/sizeof(code[0]), .filter = code, }; int main(){ int soc; struct ifreq ifr; struct sockaddr_ll sll; unsigned char buf[4096]; memset(&ifr, 0, sizeof(ifr)); memset(&sll, 0, sizeof(sll)); soc = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); strncpy(ifr.ifr_name, "br0", IFNAMSIZ); ioctl(soc, SIOCGIFINDEX, &ifr); sll.sll_family = AF_PACKET; sll.sll_protocol = htons(ETH_P_ALL); sll.sll_ifindex = ifr.ifr_ifindex; bind(soc, (struct sockaddr *)&sll, sizeof(sll)); setsockopt(soc, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf)); while(1){ ssize_t len = recv(soc, buf, sizeof(buf), 0); struct ethhdr* ethhdr = (struct ethhdr*)buf; int proto = ntohs(ethhdr->h_proto); if(len <= 0) break; printf("%3ld %0x %s\n", len, proto, proto==ETH_P_ARP ? "arp" : proto==ETH_P_IP ? "ip" : "other"); } return 0; }
ãã®ããã°ã©ã ãå®è¡ããã¨ï¼ARPã®ãã±ãããåä¿¡ãããã¨ããåºåãããªãã¯ãã§ãï¼ ããã§éè¦ãªãã¨ã¯ï¼ãã£ã«ã¿ãªã³ã°ãã«ã¼ãã«ç©ºéã§è¡ããã¦ãããã¨ï¼ã¾ãã¦ã¼ã¶ãå®ç¾©ããããã°ã©ã ãã«ã¼ãã«å ã§åä½ãã¦ãããã¨ã§ãï¼
libpcapã¨BPF
å ã»ã©ã¯ãã£ã«ã¿ããã°ã©ã ã¯ãã¯ãã使ã£ã¦å®ç¾©ãã¾ãããï¼ãã±ãããã£ããã£ã©ã¤ãã©ãªã¨ãã¦æåãªlibpcapã¯ãã±ããã®ãã£ã«ã¿ãªã³ã°ã« BPFãå©ç¨ãã¦ããï¼å®ã¯tcpdumpã使ãã¨ãã£ã«ã¿å¼ãBPFã®ããã°ã©ã ã«ã³ã³ãã¤ã«ãããã¨ãã§ãã¾ãï¼ã¨ãããããããtcpdumpãBPFãæåã«ä½¿ã£ãããã°ã©ã ã ã£ãã½ãï¼ *5ï¼
% sudo tcpdump -d arp (000) ldh [12] (001) jeq #0x806 jt 2 jf 3 (002) ret #262144 (003) ret #0 % sudo tcpdump -dd arp { 0x28, 0, 0, 0x0000000c }, { 0x15, 0, 1, 0x00000806 }, { 0x6, 0, 0, 0x00040000 }, { 0x6, 0, 0, 0x00000000 }, % sudo tcpdump -ddd arp 4 40 0 0 12 21 0 1 2054 6 0 0 262144 6 0 0 0
BPFã§ãã£ã«ã¿ãªã³ã°ãããã®ãªãæ®éã¯ãã®ã³ã³ãã¤ã«çµæãåãè¾¼ãã°ããã§ãããï¼æé©åããã¦ããã¾ãï¼
ã¾ãï¼libpcapã®pcap_compile
ã¨ãã颿°ã§ããã°ã©ã å
ã§ã³ã³ãã¤ã«ãããã¨ãã§ãã¾ãï¼
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <arpa/inet.h> #include <linux/if_ether.h> #include <linux/filter.h> #include <netpacket/packet.h> #include <net/if.h> #include <pcap/pcap.h> #include <pcap/bpf.h> int main(){ int soc; struct ifreq ifr; struct sockaddr_ll sll; unsigned char buf[4096]; memset(&ifr, 0, sizeof(ifr)); memset(&sll, 0, sizeof(sll)); soc = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); strncpy(ifr.ifr_name, "br0", IFNAMSIZ); ioctl(soc, SIOCGIFINDEX, &ifr); sll.sll_family = AF_PACKET; sll.sll_protocol = htons(ETH_P_ALL); sll.sll_ifindex = ifr.ifr_ifindex; bind(soc, (struct sockaddr *)&sll, sizeof(sll)); struct bpf_program bpf; pcap_t *handle; handle = pcap_open_live("br0", 4096, 1, 1000, buf); pcap_compile(handle,&bpf,"arp",1,PCAP_NETMASK_UNKNOWN); setsockopt(soc, SOL_SOCKET, SO_ATTACH_FILTER, (struct sock_fprog*)&bpf, sizeof(bpf)); while(1){ ssize_t len = recv(soc, buf, sizeof(buf), 0); struct ethhdr* ethhdr = (struct ethhdr*)buf; int proto = ntohs(ethhdr->h_proto); if(len <= 0) break; printf("%3ld %0x %s\n", len, proto, proto==ETH_P_ARP ? "arp" : proto==ETH_P_IP ? "ip" : "other"); } return 0; }
...ã¾ãããããlibpcap使ãã®ãªããã£ããã£ç¨ã«ä¾¿å©ãªé¢æ°ãããããããã®ã§ããã使ã£ãæ¹ãããã¨æãã¾ããï¼ libpcapã«ã¯BPFããã°ã©ã ã®ã¤ã³ã¿ããªã¿ãä»å±ãã¦ãã¦ï¼ã¦ã¼ã¶ç©ºéã§ãã±ããã®ãã£ã«ã¿ãªã³ã°ããããå ´åã«ä½¿ãã¾ãï¼
ã¾ãï¼Linuxã®ã½ã¼ã¹ã®tools/net以ä¸ã«ãbpfã®ã¢ã»ã³ãã©ãªã©ã®ãã¼ã«ãããã¾ãï¼ãããã®ä½¿ãæ¹ã¯ ããã¥ã¡ã³ã[7]ã«æ¸ãã¦ããã¾ãï¼
ããã¾ã§ã®ã¾ã¨ã
- BPFã¨ãããã±ãããã£ã«ã¿ãªã³ã°æ©æ§ãããï¼
- BPFã¯ãã±ãããã£ããã£é¨åã¨ãã£ã«ã¿ãªã³ã°é¨åã«åãããï¼ãã£ã«ã¿ãªã³ã°ã¯ä»®æ³çãªã¬ã¸ã¹ã¿ãã·ã³ã使ç¨ããï¼
- Linuxã®Linux Socket Filterã¯BPFã§ãã£ã«ã¿ãªã³ã°ããããªãï¼
- Linuxã§ã¯
setsockopt(2)
ã§ã½ã±ããã«å¯¾ãã¦ãã£ã«ã¿ãªã³ã°ãããBPFããã°ã©ã ãè¨å®ã§ããï¼ - tcpdump(libpcap)ã使ã£ã¦BPFããã°ã©ã ã¯ã³ã³ãã¤ã«ã§ããï¼
次åã¯seccompãBPFãã©ã®ããã«å©ç¨ãã¦ãããã«ã¤ãã¦æ¸ããã¨æãã¾ãï¼
åèæç®
- [1]Steven McCanne and Van Jacobson. 1993. The BSD packet filter: a new architecture for user-level packet capture. In Proceedings of the USENIX Winter 1993 Conference Proceedings on USENIX Winter 1993 Conference Proceedings (USENIX'93). USENIX Association, Berkeley, CA, USA, 2-2
- [2]seccomp(2) - Linux manual page
- [3]Kprobe-based Event Tracing
- [4]MOGUL, J.C., RASHID, R.F., AND ACCETTA, M.J. The packet filter: An efficient mechanism for user-level network code. In Proceedings of 11th Symposium on Operating Systems Principles (Austin, TX, Nov. 1987), ACM, pp. 39â51
- [5]Ethernet - The Wireshark Wiki
- [6]packet(7) - Linux manual page
- [7]Linux Socket Filtering aka Berkeley Packet Filter (BPF)
- [8]bpf(4)
- [9]getsockopt(2) - Linux manual page
ãã®ä»åèURL
- Berkeley Packet Filterã®åºç¤ã¨å¿ç¨ - Part 1
- Net bsd advent calendar 2015 BPF Programming basic
*1:è«æãåºãã®ã93å¹´ã§å®éã«ã¯ãã®2å¹´ãããåããåå¨ãã¦ããããã§ã
*2:ããã§BPFã¯BPFã®ãã£ã«ã¿ãªã³ã°æ©æ§ã®ãã¨ãæãã¦ãã¾ã
*3:Linux 4.7ããperfã®eventããµãã¼ãããã¾ãã
*4:è¯ãåã¯ã¨ã©ã¼ãã³ããªã³ã°ãã¾ããã
*5:BPFããã°ã©ã ã®ã³ã¼ãã«ã¤ãã¦ï¼çµ±ä¸çãªä»æ§ã¯ç§ã¯ç¥ãã¾ãããï¼LinuxãBSDãåããã®ãå©ç¨ãã¦ããããã§ã