BPF(4)

명칭
bpf - 버크 레이 패킷 필터

서식
pseudo-device bpfilter

해설
버크 레이 패킷 필터는, 데이터 링크층에 있어 프로토콜비의존의 생의형태의 인터페이스를 제공합니다. 네트워크상의 패킷은, 비록 다른 호스트로 향해졌다 물건이어도, 모두 이 기구를 통해 액세스 할 수가 있습니다.

이 패킷 필터는 /dev/bpf0, /dev/bpf1 등의 캐릭터형 특수 디바이스로 보입니다. 이 디바이스를 오픈한 후, 파일 기술자는 BIOCSETIF ioctl 에 의해, 특정의 네트워크 인터페이스에 묶지 않으면 안됩니다. 지시받은 인터페이스는 복수의 감시자로 공유할 수가 있어 각 기술자아래에 있는 필터는, 같은 패킷의 흐름을 보게 됩니다. 오픈할 수 있는 파일의 상한은, 커널의 설정으로 주어진 값에 제한됩니다. 위의 서식 그리고 주어진 예에서는, 제한은 16 이 되어 있습니다.

각각의 마이나데바이스에는, 다른 디바이스 파일이 필요합니다. 디바이스 파일이 사용중이다면, 오픈은 실패해, errno 에는 EBUSY 가 세트 됩니다.

오픈되었다 bpf 파일의 실체 각각 관련 지을 수 있고 있는 것이, 유저가 설정 가능한 패킷 필터입니다. 어느 인터페이스로 패킷을 수신했을 때는 언제라도, 그 인터페이스를 감시하고 있는 파일 기술자는 모두 자신의 필터를 적용합니다. 패킷을 받는 각 기술자는, 자신용의 카피를 받습니다.

각각의 파일로부터의 입력은, 필터로 매치 한 패킷의 다음의 그룹을 돌려줍니다. 성능을 올리기 위해서(때문에), read 에 건네주는 버퍼는 bpf 하지만 내부에서 사용하는 버퍼와 같은 사이즈가 아니면 안됩니다. 이 사이즈는, BIOCGBLEN ioctl (아래와 같이를 참조)로 얻을 수 있어 BIOCSBLEN 그리고 설정할 수 있습니다. 이 사이즈보다 큰 개개의 패킷은, 필연적으로 절약할 수 있어 버리는 것에 주의해 주세요.

이 패킷 필터는, 고정장 헤더이면 어느 링크 레벨 프로토콜에서도 서포트합니다. 현재, 이더넷(ethernet)와 SLIP (와)과 PPP 드라이버만이 bpf (와)과 협조해 동작하도록(듯이) 수정되고 있습니다.

패킷 데이터는 네트워크 바이트 오더가 되어 있으므로, 어플리케이션이 복수 바이트의 값을 꺼내기 위해서(때문에)는 byteorder(3) 매크로를 사용하지 않으면 안됩니다.

bpf 파일 기술자에게 기입하는 것으로 네트워크에 패킷을 송출할 수가 있습니다. 기입은 버퍼링 되지 않기 때문에, 1 회의 기입에 대해 1 개의 패킷밖에 처리되지 않습니다. 현재 이더넷(ethernet)와 SLIP 링크에의 기입만이 서포트되고 있습니다.

IOCTL
다음과 같은 ioctl(2) 명령 코드가 <net/bpf.h> 로 정의되고 있습니다. 모든 커멘드에는 다음과 같은 인클루드 파일이 필요합니다.

    	#include <sys/types.h>
    	#include <sys/time.h>
    	#include <sys/ioctl.h>
    	#include <net/bpf.h>

게다가 BIOCGETIF (와)과 BIOCSETIF (은)는, <sys/socket.h> (와)과 <net/if.h> (을)를 필요로 합니다. FIONREAD (와)과 SIOCGIFADDR 이외로도, 다음과 같은 명령을 오픈했다 bpf 파일에 적용할 수 있습니다. ioctl(2) 에의 (3 번째의) 인수는, 지정의 형태에의 포인터가 아니면 안됩니다.

BIOCGBLEN
    (u_int) bpf 파일상에서 읽기를 실시하기 위해서(때문에) 필요한 버퍼장을 돌려줍니다.

BIOCSBLEN
    (u_int) bpf 파일상에서 읽기를 행하기 위한 버퍼장을 설정합니다. 버퍼는, 파일이 BIOCSETIF 에 의해 인터페이스에 접속되기 전으로 설정되지 않으면 안됩니다. 요구된 버퍼 사이즈를 적용할 수 없었던 경우는, 허용 할 수 있는 사이즈로 가장 가까운 것으로 설정되어 그것이 인수안에 돌려주어집니다. 이 사이즈가 아닌 패킷이 버퍼를 다녔을 때에는, 읽기 콜은 EIO 의 값으로 종료합니다.

BIOCGDLT
    (u_int) 접속된 인터페이스아래에 있는 데이터 링크층의 형태를 돌려줍니다. 인터페이스가 지정되어 있지 않았던 경우 EINVAL 하지만 돌려주어집니다. 디바이스의 형태는, “DLT_” 하지만 전을 뒤따른 형태이며, <net/bpf.h> 그리고 정의되고 있습니다.

BIOCPROMISC
    강제적으로 인터페이스를 무차별 (promiscuous) 모드로 합니다. 로컬 호스트로 향해진 것만 안되어 모든 패킷이 처리됩니다. 복수의 파일이 주어진 인터페이스를 감시할 수가 있으므로, 그 인터페이스를 무차별하지 않은 모드로 오픈한 감시자라도 패킷을 무차별하게 수신하는 것이 가능하게 됩니다. 이 문제는 적당한 필터로 교정할 수가 있습니다.

BIOCFLUSH
    도착 패킷의 버퍼를 플래시 해, BIOCGSTATS 로 돌려주어진다 집계치를 리셋트 합니다.

BIOCGETIF
    (struct ifreq) 파일이 감시하고 있는 하드웨어인터페이스의 이름을 돌려줍니다. 이름은 ifreq 구조체의 ifr_name 필드에 돌려주어집니다. 다른 필드는 모두 미정도리가 됩니다.

BIOCSETIF
    (struct ifreq) 파일에 관련짓는 하드웨어인터페이스를 설정합니다. 이 명령은, 어떤 패킷을 읽어들이는 것보다도 전에 실행되지 않으면 안됩니다. 디바이스는, ifreq 구조체의 ifr_name 필드를 사용해 이름으로 나타납니다. 한층 더 BIOCFLUSH 의 동작을 실행합니다.

BIOCSRTIMEOUT

BIOCGRTIMEOUT
    (struct timeval) 타임 아웃 파라미터를 설정 또는 취득합니다. 인수에는, 읽기 요구로 타임 아웃 할 때까지의 대기 시간의 길이를 지정합니다. 이 파라미터는, open(2) 에 의해 0 에 초기화되어 타임 아웃 하지 않는 것을 지시합니다.

BIOCGSTATS
    (struct bpf_stat) 패킷 집계치의 다음의 구조체를 돌려줍니다:

        struct bpf_stat {
        	u_int bs_recv;    /* 수신한 패킷수 */
        	u_int bs_drop;    /* 떨어뜨린 패킷수 */
        };

    필드는 다음과 같이 됩니다:

    bs_recv
        오픈 또는 리셋트 후에, 이 기술자에 의해 수신한 패킷수 (마지막 읽기 콜로부터 버퍼 되고 있는 것을 포함합니다).

    bs_drop
        필터가 수취는 했지만, 버퍼의 오버플로우에 의해 커널이 떨어뜨린 패킷의 수 (즉, 어플리케이션의 읽기가 패킷의 유량을 따라 잡지 않았다 그렇다고 하는 것입니다).

BIOCIMMEDIATE
    (u_int) 인수의 진위치에 근거해 ``직접 모드''를 유효 또는 무효로 합니다. 직접 모드가 유효한 때, 패킷을 받으면(자) 읽기는 즉시 돌려주어집니다. 무효인이라고 해 입력은 커널 버퍼가 가득 차는지, 또는 타임 아웃이 일어날 때까지 블록 됩니다. 이것은, 리얼타임에 메세지에 응답해야 한다 rarpd(8) (와)과 같은 프로그램에는 편리합니다. 새로운 파일에 대해서는, 디폴트에서는 오프가 됩니다.

BIOCSETF
    (struct bpf_program) 흥미가 없는 패킷을 버리기 위해서(때문에) 커널이 사용하는 필터 프로그램을 설정합니다. 다음의 구조체를 통해 인스트럭션을 늘어놓은 배열과 그 길이가 건네받습니다:

        struct bpf_program {
        	int bf_len;
        	struct bpf_insn *bf_insns;
        };

    필터 프로그램은 bf_insns 필드에서 지정되어 ‘struct bpf_insn’ 의 구조 체내에 있어서의 프로그램의 길이가 bf_len 필드에서 주어집니다. 그리고, BIOCFLUSH 의 동작이 실행됩니다. 필터 언어의 설명에 대해서는 필터 머신 의 섹션을 봐 주세요.

BIOCVERSION
    (struct bpf_version) 현재 커널에 인식되고 있는 필터 언어의 메이저 및 마이나바젼 번호를 돌려줍니다. 필터를 인스톨 하기 전에, 어플리케이션은, 동작하고 있는 커널과 현재의 버젼이 호환성이 있는지 어떤지를 조사하지 않으면 안됩니다. 메이저 번호가 일치해, 어플리케이션의 마이나 번호가 커널의 마이나 번호에 동일한지, 그것 이하라면 버젼 번호는 호환성이 있습니다. 커널의 버젼 번호는 이하의 구조체로 돌려주어집니다:

        struct bpf_version {
                u_short bv_major;
                u_short bv_minor;
        };

    현재의 버젼 번호는 <net/bpf.h> 안의 BPF_MAJOR_VERSION (와)과 BPF_MINOR_VERSION 에 의해 주어집니다. 호환성이 없는 필터에서는, 예기치 않은 동작에 끝날지도 모릅니다 (가장 있을 것인 것은, ioctl() 에 의해 에러가 돌려주어지는지, 또는 우연히 패킷이 일치하는 것입니다).

BPF 헤더
read(2) 에 의해 돌려주어지는 각 패킷의 선두에는, 다음과 같은 구조체가 붙여져 있습니다:

    struct bpf_hdr {
            struct timeval bh_tstamp;     /* 타임 스탬프 */
            u_long bh_caplen;             /* capther 된 부분의 길이 */
            u_long bh_datalen;            /* 패킷의 오리지날의 길이 */
            u_short bh_hdrlen;            /* bpf 헤더의 길이 (이 구조체
    					 + 경계 조정 패딩) */
    };

필드는 호스트순서로 보존되고 있어 다음과 같이 됩니다:

bh_tstamp
    패킷 필터에 의해, 그 패킷이 처리되었을 때 각
bh_caplen
    패킷의 capther 된 부분의 길이. 이것은 절약하고 양의 최소치로, 필터와 패킷장에 의해 지정되어 있습니다.
bh_datalen
    경로로부터 멀어진 패킷장. 이 값은 필터로 지정된 절약하고 양에는 의존하지 않습니다.
bh_hdrlen
    bpf 헤더의 길이. 이것은 sizeof(struct bpf_hdr) 에 동일하다고는 할 수 없습니다.

bh_hdrlen 필드는 헤더와 링크 레벨 프로토콜간의 패딩을 위해서(때문에) 존재합니다. 이 목적은, 패킷 데이터 구조의 적절한 경계 조정을 프로텍션하는 것입니다. 이것은, 경계 조정에 어려운 아키텍쳐가 필요로 하는 것이어, 또, 이것에 의해 다른 많은 아키텍쳐에 있어서의 성능이 향상합니다. 패킷 필터는 bpf_hdr (와)과 네트워크층의 헤더가 워드 경계가 되는 것을 프로텍션합니다. 경계 조정이 제약된 머신상에서 링크층 프로토콜을 액세스 할 경우에는, 적절한 주위를 기울이지 않으면 안됩니다 (이것은 이더넷(ethernet)상에서는 문제로는 되지 않습니다. 왜냐하면, 필드의 형태가 short 이며 짝수 오프셋(offset)에 안정되고, 주소가 아마 바이트 단위로 액세스 되기 때문입니다).

게다가 개개의 패킷은 워드 경계에서 시작되도록(듯이) 패딩 됩니다. 이것에 의해, 어플리케이션은 패킷으로부터 다음의 패킷을 얻는 방법을 알고 있는 것이 요구됩니다. 이 프로세스를 돕기 위해서(때문에), 매크로 BPF_WORDALIGN 하지만 <net/bpf.h> 안으로 정의되고 있습니다. 인수는 가장 가까운 워드 경계치 (워드가 BPF_ALIGNMENT 바이트폭)에 끝맺을 수 있습니다.

예를 들면 ‘p’ 하지만 패킷의 선두를 가리킬 때, 다음의 표현은 포인터를 다음의 패킷에 진행합니다:
    p = (char *) p + BPF_WORDALIGN(p->bh_hdrlen + p->bh_caplen)

경계 조정의 기구를 적절히 동작시키기 위해서(때문에) read(2) 에게 건네지는 버퍼는, 그것 자신이 워드 경계에 없으면 안됩니다. malloc(3) 함수는 항상 워드 경계의 버퍼를 돌려줍니다.

필터 머신
필터 프로그램은 인스트럭션을 늘어놓은 배열이며, 모든 분기가 코드의 전방을 향하는 것이어, 또, return 인스트럭션으로 끝나는 것입니다. 각 인스트럭션은, 누산기, 인덱스 레지스터, 일시 메모리 기억, 및 암묵의 프로그램 카운터로부터 완성되는 유사 머신 상태상에서 어떠한 동작을 행합니다. 다음의 구조체가 인스트럭션 포맷의 정의입니다:

    struct bpf_insn {
    	u_short	code;
    	u_char 	jt;
    	u_char 	jf;
    	u_long k;
    };

k 필드는 인스트럭션에 따라서 다른 용법으로 이용되어 jt (와)과 jf 필드는 분기 인스트럭션에 의해 오프셋(offset)로서 이용됩니다. 조작 코드는 반계층적인 형태로 encode 됩니다. 인스트럭션에는 8 개의 클래스 BPF_LD, BPF_LDX, BPF_ST, BPF_STX, BPF_ALU, BPF_JMP, BPF_RET, BPF_MISC (이)가 있습니다. 다른 여러가지 모드와 조작 비트는 실제의 인스트럭션을 주기 위해서(때문에) 비트 가산 (or)되어 클래스에 변환됩니다. 클래스와 모드는 <net/bpf.h> 안에서 정의되고 있습니다. 이하는 정의된 각각의 bpf 인스트럭션입니다. 편의적으로 A 가 누산기, X 가 인덱스 레지스터, P[] 가 패킷 데이터, M[] 가 오합지졸의 일시 메모리 기억이다고 합니다. P[i:n] 는 패킷내의 ``i''바이트 오프셋(offset)의 데이터를 가리켜, 워드 (n=4), 부호 없음반워드 (n=2), 부호 없음 바이트 (n=1) (으)로 번역됩니다. M[i] 는, 일시 메모리 기억 중(안)에서 i 번째의 워드를 가리켜, 워드 단위의 주소만이 할당해집니다. 메모리 기억은 0 으로부터 BPF_MEMWORDS - 1 에 번호 붙이고 됩니다. k, jt, jf (은)는, 인스트럭션 정의 중(안)에서 대응하는 필드가 됩니다. ``len''는, 패킷장을 참조합니다.

BPF_LD
    이러한 인스트럭션은, 값을 누산기에 복사합니다. 소스 오퍼랜드의 형태는,``addressing mode''로 지정되어 정수 (BPF_IMM) 그렇지만, 고정 오프셋(offset)의 패킷 데이터 (BPF_ABS) , 가변 오프셋(offset)의 패킷 데이터 (BPF_IND) , 패킷장 (BPF_LEN) , 일시 메모리 기억내의 워드 (BPF_MEM) (을)를 취할 수 있습니다. BPF_IND (와)과 BPF_ABS 의 경우, 데이터 사이즈는, 워드 (BPF_W) , 하프 워드 (BPF_H) , 바이트 (BPF_B) 의 언젠가가 아니면 안됩니다. 사용 가능한 전 BPF_LD 인스트럭션의 의미는 다음과 같습니다.

    BPF_LD+BPF_W+BPF_ABS
        A <- P[k:4]
    BPF_LD+BPF_H+BPF_ABS
        A <- P[k:2]
    BPF_LD+BPF_B+BPF_ABS
        A <- P[k:1]
    BPF_LD+BPF_W+BPF_IND
        A <- P[X+k:4]
    BPF_LD+BPF_H+BPF_IND
        A <- P[X+k:2]
    BPF_LD+BPF_B+BPF_IND
        A <- P[X+k:1]
    BPF_LD+BPF_W+BPF_LEN
        A <- len
    BPF_LD+BPF_IMM
        A <- k
    BPF_LD+BPF_MEM
        A <- M[k]
BPF_LDX
    이러한 인스트럭션은 값을 인덱스 레지스터에 로드합니다. 이 인스트럭션 때의 addressing mode는, 누산기에의 로드 때보다 엄밀합니다만, IP 헤더장을 로드하는 효과적인 방법이다 BPF_MSH (을)를 포함하고 있는 것에 주목해 주세요.
    BPF_LDX+BPF_W+BPF_IMM
        X <- k
    BPF_LDX+BPF_W+BPF_MEM
        X <- M[k]
    BPF_LDX+BPF_W+BPF_LEN
        X <- len
    BPF_LDX+BPF_B+BPF_MSH
        X <- 4*(P[k:1]&0xf)
BPF_ST
    이 인스트럭션은 누산기를 일시 메모리에 퇴피합니다. 행선지의 가능성이 하나 밖에 없기 때문에 addressing mode는 불필요합니다.
    BPF_ST
        M[k] <- A
BPF_STX
    이 인스트럭션은 인덱스 레지스터를 일시 메모리에 퇴피합니다.
    BPF_STX
        M[k] <- X
BPF_ALU
    alu 인스트럭션은, 누산기와 인덱스 레지스터 또는 정수간의 조작을 실행해, 결과를 누산기에 되돌립니다. 바이너리 조작을 위해서(때문에)는 소스 모드가 필요합니다 ( BPF_K 또는 BPF_X
    BPF_ALU+BPF_ADD+BPF_K
        A <- A + k
    BPF_ALU+BPF_SUB+BPF_K
        A <- A - k
    BPF_ALU+BPF_MUL+BPF_K
        A <- A * k
    BPF_ALU+BPF_DIV+BPF_K
        A <- A / k
    BPF_ALU+BPF_AND+BPF_K
        A <- A & k
    BPF_ALU+BPF_OR+BPF_K
        A <- A | k
    BPF_ALU+BPF_LSH+BPF_K
        A <- A << k
    BPF_ALU+BPF_RSH+BPF_K
        A <- A >> k
    BPF_ALU+BPF_ADD+BPF_X
        A <- A + X
    BPF_ALU+BPF_SUB+BPF_X
        A <- A - X
    BPF_ALU+BPF_MUL+BPF_X
        A <- A * X
    BPF_ALU+BPF_DIV+BPF_X
        A <- A / X
    BPF_ALU+BPF_AND+BPF_X
        A <- A & X
    BPF_ALU+BPF_OR+BPF_X
        A <- A | X
    BPF_ALU+BPF_LSH+BPF_X
        A <- A << X
    BPF_ALU+BPF_RSH+BPF_X
        A <- A >> X
    BPF_ALU+BPF_NEG
        A <- -A
BPF_JMP
    점프 인스트럭션은 flow control를 변경합니다. 조건 점프는 누산기와 정수 (BPF_K) 또는 인덱스 레지스터 (BPF_X) 사이의 비교를 행합니다. 결과가 진 (즉 비 0)이었을 경우에 진정한 분기가 선택되어 그렇지 않으면 가짜의 분기가 선택됩니다. 점프 오프셋(offset)는 8 비트에 encode 되므로, 최장 점프는 256 인스트럭션분입니다. 그러나, 상시 점프 조작 코드 (BPF_JA) (은)는, 오프셋(offset)로서 32 비트의 k 필드를 사용해, 떨어진 임의의 행선지를 허락합니다. 모든 조건은 관습적으로 부호 없음 비교를 이용합니다.
    BPF_JMP+BPF_JA
        pc += k
    BPF_JMP+BPF_JGT+BPF_K
        pc += (A > k) ? jt : jf
    BPF_JMP+BPF_JGE+BPF_K
        pc += (A >= k) ? jt : jf
    BPF_JMP+BPF_JEQ+BPF_K
        pc += (A == k) ? jt : jf
    BPF_JMP+BPF_JSET+BPF_K
        pc += (A & k) ? jt : jf
    BPF_JMP+BPF_JGT+BPF_X
        pc += (A > X) ? jt : jf
    BPF_JMP+BPF_JGE+BPF_X
        pc += (A >= X) ? jt : jf
    BPF_JMP+BPF_JEQ+BPF_X
        pc += (A == X) ? jt : jf
    BPF_JMP+BPF_JSET+BPF_X
        pc += (A & X) ? jt : jf
BPF_RET
    리턴 인스트럭션은 필터 프로그램을 종료해, 수신하는 패킷의 양을 지정합니다 (즉, 절약하고 양을 돌려줍니다). 반환값 0 은, 그 패킷이 무시 되는 것이 당연한 것을 나타내고 있습니다. 반환값은 정수 (BPF_K) 또는 누산기 (BPF_A) 의 머지않아인가입니다.
    BPF_RET+BPF_A
        A 바이트 수신
    BPF_RET+BPF_K
        k 바이트 수신
BPF_MISC
    상기의 클래스에 적합하지 않는 것이나, 추가되어야 한다 새로운 인스트럭션 (을)를 위해서(때문에), 그 외의 카테고리가 만들어졌습니다. 현재, 인덱스 레지스터를 누산기에 복사하는, 또는 그 역을 행하는 레지스터 전송 인스트럭션이 있습니다.
    BPF_MISC+BPF_TAX
        X <- A
    BPF_MISC+BPF_TXA
        A <- X

    bpf 인터페이스는, 배열의 초기화를 돕는 다음의 매크로를 제공하고 있습니다: BPF_STMT(opcode, operand) (와)과 BPF_JUMP(opcode, operand, true_offset, false_offset)

사용예
이하의 필터가 RARP demon로부터 취득됩니다. 필터는, RARP 요구만을 수신합니다.

    struct bpf_insn insns[] = {
    	BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
    	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_REVARP, 0, 3),
    	BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20),
    	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, REVARP_REQUEST, 0, 1),
    	BPF_STMT(BPF_RET+BPF_K, sizeof(struct ether_arp) +
    		 sizeof(struct ether_header)),
    	BPF_STMT(BPF_RET+BPF_K, 0),
    };

이 필터는 128.3. 112.15 로 128.3. 112.35 의 사이의 IP 패킷 만을 받습니다.

    struct bpf_insn insns[] = {
    	BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
    	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_IP, 0, 8),
    	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
    	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
    	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
    	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4),
    	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
    	BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
    	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1),
    	BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
    	BPF_STMT(BPF_RET+BPF_K, 0),
    };

마지막으로, 이 필터는 TCP finger 패킷만을 돌려줍니다. TCP 헤더에 가까스로 도착하기 위해서(때문에)는 IP 헤더를 해석하지 않으면 안됩니다. BPF_JSET 인스트럭션은 IP fragment 오프셋(offset)가 0 인 것을 조사합니다. 그래서 TCP 헤더인 것을 확인합니다.

    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, 79, 2, 0),
    	BPF_STMT(BPF_LD+BPF_H+BPF_IND, 16),
    	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 0, 1),
    	BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
    	BPF_STMT(BPF_RET+BPF_K, 0),
    };

관련 항목
tcpdump(1), ioctl(2), byteorder(3) McCanne, S., Jacobson V., An efficient, extensible, and portable network monitor.

관련 파일
/dev/bpfn
    패킷 필터 디바이스

버그
읽기 버퍼는 고정장 ( BIOCGBLEN ioctl 로 돌려주어지는 값)이 아니면 안됩니다.

무차별 모드를 요구하지 않는 파일은, 같은 하드웨어인터페이스상에서 이 모드를 요구하는 다른 파일의 부작용으로서 무차별하게 패킷을 수신할지도 모릅니다. 이것은, 오버헤드가 있는 처리를 추가하면, 커널내에서 수정할 수 있겠지요. 그러나, 인터페이스는 무차별하다라고 모든 파일이 간주하지 않으면 안 되는 것 같은 모델이 선호됩니다. 필요하면, 외부의 패킷을 튕기기 위한 필터를 이용하지 않으면 안됩니다.

가변장 헤더의 데이터 링크 프로토콜은 현재 서포트되고 있지 않습니다.

역사

Enet 패킷 필터는, 1980 년에 카네기 멜론 대학의 Mike Accetta 와 Rick Rashid 에 의해 작성되었습니다. 스탠포드의 Jeffrey Mogul 가 코드를 BSD 에 이식해 1983 년 이후 발전시켰습니다. 그 후 DEC 의 Ultrix 패킷 필터, SunOS 4.1 의 STREAMS NIT 모듈, BPF (으)로 진화했습니다.

저자
Lawrence Berkeley 연구소의 Steven McCanne 하지만 1990 년 여름에 BPF 를 인플리맨트 했습니다. 많게는 Van Jacobson 에 의해 디자인되었습니다.