Linux 커널에서 BPF (Berkeley packet filter)라는 비슷한 메커니즘이 있습니다. 응용 프로그램에서 BPF 필터를 커널에 등록하십시오. 필터와 일치하는 패킷은 캡처되어 등록 된 후크 기능으로 전달됩니다.
아래는 인터넷에서 발견 한 exmpale 코드입니다. (https://gist.github.com/939154) 기본적으로 BPF 필터로 바인딩을 열고 바인딩을 선택하고 패킷을 수신하기 위해이 FD를 선택해야합니다. ; set_filter (int fd) { struct bpf_program fcode = {0};
/* dump ssh packets only */
struct bpf_insn insns[] = {
BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_IP, 0, 10),
BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 23),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_TCP, 0, 8),
BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20),
BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 0x1fff, 6, 0),
BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 14),
BPF_STMT(BPF_LD+BPF_H+BPF_IND, 14),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 22, 2, 0),
BPF_STMT(BPF_LD+BPF_H+BPF_IND, 16),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 22, 0, 1),
BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
BPF_STMT(BPF_RET+BPF_K, 0),
};
/* Set the filter */
fcode.bf_len = sizeof(insns)/sizeof(struct bpf_insn);
fcode.bf_insns = &insns[0];
if(ioctl(fd, BIOCSETF, &fcode) < 0)
return -1;
return 0;
}
bpf_inst는 terrbiel 보인다. 그러나 수동으로 작성하지 않아도됩니다. tcp-dump를 사용하여이 스크립트를 자동 생성 할 수 있습니다. 예를 들어
:
sudo tcpdump 'tcp[13]=18' -i eth0 -dd
{ 0x28, 0, 0, 0x0000000c },
{ 0x15, 0, 8, 0x00000800 },
{ 0x30, 0, 0, 0x00000017 },
{ 0x15, 0, 6, 0x00000006 },
{ 0x28, 0, 0, 0x00000014 },
{ 0x45, 4, 0, 0x00001fff },
{ 0xb1, 0, 0, 0x0000000e },
{ 0x50, 0, 0, 0x0000001b },
{ 0x15, 0, 1, 0x00000012 },
{ 0x6, 0, 0, 0x00000060 },
{ 0x6, 0, 0, 0x00000000 },
여전히 bpf 장치를 읽고 패킷을 다시 써야하므로 사용자 공간 및 점프대로 점프합니다. 그러나 이것이 벤치 마크에서 벗어나기 전에. Linux 시스템 호출은 Windows보다 더 빠른 경우가 많습니다. –