ipfirewall

명칭
     ipfirewall — IP 패킷 필터 및 트래픽 측정

서식
     #include <sys/types.h>
     #include <sys/queue.h>
     #include <netinet/in.h>
     #include <netinet/ip_fw.h>
     int setsockopt(raw_socket, IPPROTO_IP, ipfw option, struct ipfw, size)

해설
     ipfirewall (별명 ipfw)는, 시스템의 인터페이스를 통과하는 IP 패킷에 대해 필터링이나 리디렉트등의 처리를 실시하는
     시스템의 기능입니다.  패킷은 적합하는 것이 발견될 때까지 패턴 룰의 순서 리스트와 비추어 합쳐지고 룰은 1 에서 65534 까지의
     번호를 차여 복수의 룰이 같은 번호를 공유하는 일도 가능합니다.

     유일 반드시 존재하는 룰로서 룰 번호 65535 가 있습니다.  이 룰은 통상은 모든 패킷을 파기합니다.  따라서, 이것보다 작은
     번호의 룰에 적합하지 않았던 패킷은 모두 파기됩니다.  그러나, 커널을 컴파일 할 때의 옵션
     “IPFIREWALL_DEFAULT_TO_ACCEPT” (을)를 지정하면(자), 관리자는 모두 (의 패킷의 통과를) 허가하도록(듯이)
     이 고정 룰을 변경할 수가 있습니다.

     setsockopt() 에 건네받는 값은, 룰을 기술하고 있는 ip_fw 구조체 (아래와 같이 참조)입니다.  (IP_FW_DEL 와
     같은) 몇개의 케이스에서는 룰 번호만이 중요하게 됩니다.

명령
     룰 리스트를 취급하기 위해서(때문에) 다음의 소켓 옵션을 사용합니다:

     IP_FW_ADD 는, 룰 리스트에 룰을 삽입합니다.

     IP_FW_DEL 는, 적합하는 룰 번호를 가지는 룰을 모두 삭제합니다.

     IP_FW_GET 는, 적합하는 룰 번호의 (최초의) 룰을 돌려줍니다.

     IP_FW_ZERO 는, 적합하는 룰 번호를 가지는 모든 룰에 관한 통계를 0 으로 합니다.  룰 번호가 0 의 경우에는 모든 룰을 0
     으로 합니다.

     IP_FW_FLUSH (65535 를 제외한다) 모든 룰을 소거합니다.

     커널의 보안 레벨이 2 보다 큰 경우는 IP_FW_GET 만이 허가됩니다.

룰 구조체
     룰은 다음의 구조체로 기술되고 있습니다:

     /* 1 개의 인터페이스를 지정 */
     union ip_fw_if {
         struct in_addr fu_via_ip;   /* IP 주소로 지정 */
         struct {                    /* 인터페이스명으로 지정 */
     #define FW_IFNLEN       6       /* 구조체를 2^x 경계에 둔다 */
                 char  name[FW_IFNLEN];
                 short unit;         /* -1 는 임의의 유니트에 적합 */
         } fu_via_if;
     };

     /* 1 개의 ipfw 룰 */
     struct ip_fw {
         u_long fw_pcnt, fw_bcnt;         /* 패킷과 바이트수의 카운터 */
         struct in_addr fw_src, fw_dst;  /* 시점과 종점의 IP 주소 */
         struct in_addr fw_smsk, fw_dmsk;/* 시점과 종점의 IP 주소의 마스크 */
         u_short fw_number;              /* 룰 번호 */
         u_short fw_flg;                 /* 플래그어 */
     #define IP_FW_MAX_PORTS 10          /* 정도 좋은 최대치 */
         u_short fw_pts[IP_FW_MAX_PORTS];/* 적합하는 포트 번호의 배열 */
         u_char fw_ipopt, fw_ipnopt;      /* IP 옵션세트/안 세트 */
         u_char fw_tcpf, fw_tcpnf;        /* TCP 플래그세트/안 세트 */
     #define IP_FW_ICMPTYPES_DIM (256 / (sizeof(unsigned) * 8))
         unsigned fw_icmptypes[IP_FW_ICMPTYPES_DIM]; /* ICMP 타입의 비트 맵 */
         long timestamp;                 /* 최종 적합의 타임 스탬프 (tv_sec) */
         union ip_fw_if fw_in_if, fw_out_if;/* 입력/출력의 인터페이스 */
         union {
             u_short fu_divert_port;     /* Divert/tee 포트 */
             u_short fu_skipto_rule;     /* SKIPTO 명령 룰 번호 */
             u_short fu_reject_code;     /* REJECT 응답 코드 */
         } fw_un;
         u_char fw_prot;                 /* IP 프로토콜 */
         u_char fw_nports;               /* 포트 배열중의, 시점 포토수와   */
                                         /* 종점 포트수 (종점 포토가 시점   */
                                         /* 포트에 후속. 최대로 합계 10 포토 */
                                         /* 0 은 전포트 매치의 의미)        */
     };

     /* 시점/종점의 포트수를 "fw_nports" 에 encode */

     #define IP_FW_GETNSRCP(rule)            ((rule)->fw_nports & 0x0f)
     #define IP_FW_SETNSRCP(rule, n)         do {                            \
                                               (rule)->fw_nports &= ~0x0f;   \
                                               (rule)->fw_nports |= (n);     \
                                             } while (0)
     #define IP_FW_GETNDSTP(rule)            ((rule)->fw_nports >> 4)
     #define IP_FW_SETNDSTP(rule, n)         do {                            \
                                               (rule)->fw_nports &= ~0xf0;   \
                                               (rule)->fw_nports |= (n) << 4;\
                                             } while (0)

     /* flags" 필드용 플래그치 */

     #define IP_FW_F_IN      0x0001  /* 입력 패킷을 체크               */
     #define IP_FW_F_OUT     0x0002  /* 출력 패킷을 체크               */
     #define IP_FW_F_IIFACE  0x0004  /* 입력 인터페이스 테스트를 적용       */
     #define IP_FW_F_OIFACE  0x0008  /* 출력 인터페이스 테스트를 적용       */

     #define IP_FW_F_COMMAND 0x0070  /* 연쇄형 엔트리용의 마스크             */
     #define IP_FW_F_DENY    0x0000  /* 이것은 거부 룰                     */
     #define IP_FW_F_REJECT  0x0010  /* 거부해 응답 패킷을 송신           */
     #define IP_FW_F_ACCEPT  0x0020  /* 이것은 수리 룰                     */
     #define IP_FW_F_COUNT   0x0030  /* 이것은 계수 룰                     */
     #define IP_FW_F_DIVERT  0x0040  /* 이것은 divert 룰                 */
     #define IP_FW_F_TEE     0x0050  /* 이것은 분기 룰                     */
     #define IP_FW_F_SKIPTO  0x0060  /* 이것은 스킵 룰                 */

     #define IP_FW_F_PRN     0x0080  /* 이 룰이 적합했을 경우에 표시       */

     #define IP_FW_F_SRNG    0x0100  /* 최초의 2 개의 시점 포트는, 최소와    *
                                      * 최대의 범위 (호스트의 바이트순서로 격납)  */

     #define IP_FW_F_DRNG    0x0200  /* 최초의 2 개의 종점 포트는, 최소와    *
                                      * 최대의 범위 (호스트의 바이트순서로 격납)  */

     #define IP_FW_F_IIFNAME 0x0400  /* 입력 인터페이스는 이름/유니트    *
                                      * (IP 는 아니다)                        */
     #define IP_FW_F_OIFNAME 0x0800  /* 출력 인터페이스는 이름/유니트    *
                                      * (IP 는 아니다)                        */

     #define IP_FW_F_INVSRC  0x1000  /* 시점 체크의 의미를 반전             */
     #define IP_FW_F_INVDST  0x2000  /* 종점 체크의 의미를 반전             */

     #define IP_FW_F_FRAG    0x4000  /* 단편                                 */

     #define IP_FW_F_ICMPBIT 0x8000  /* ICMP 타입 비트 맵은 유효        */

     #define IP_FW_F_MASK    0xFFFF  /* 있을 수 있는 모든 flag bit의 마스크 */


룰의 동작
     각 룰은, 플래그어중의 IP_FW_F_COMMAND 비트로 나타나는, 다음의 동작을 가집니다.

       IP_FW_F_DENY          - 패킷을 파기합니다
       IP_FW_F_REJECT        - 패킷을 파기해, ICMP 또는 TCP 를 경유해 거부를 통지합니다
       IP_FW_F_ACCEPT        - 패킷을 받아들입니다
       IP_FW_F_COUNT         - 카운터를 증가시켜, 매칭을 계속합니다
       IP_FW_F_DIVERT        - 패킷을 divert(4) 소켓에 딴 데로 돌립니다
       IP_FW_F_TEE           - 패킷을 divert(4) 소켓에 카피해, 계속합니다
       IP_FW_F_SKIPTO        - 룰 번호 fu_skipto_rule 에 스킵 합니다

     IP_FW_F_REJECT 의 경우, fu_reject_code 의 번호가 0 에서 255 라면 대응하는 코드와 함께 수신한 패킷의
     시점의 IP 주소에 ICMP unreachable 패킷을 돌려 보냅니다.  그렇지 않는 경우에는, 값은 256 으로 프로토콜이
     IPPROTO_TCP 일 필요가 있어, 이 경우 TCP reset 패킷이 보내집니다.

     IP_FW_F_SKIPTO 을 사용하면(자), fu_skipto_rule 보다 작은 룰 번호를 가진다 모든 연속하는 룰이 스킵 됩니다.

커널 옵션
     커널 설정 파일에서의 옵션:
       IPFIREWALL               - ipfirewall 를 유효하게 합니다
       IPFIREWALL_VERBOSE       - firewall 의 출력을 유효하게 합니다
       IPFIREWALL_VERBOSE_LIMIT - firewall 의 출력을 억제합니다
       DIVERT                   - divert(4) 소켓을 유효하게 합니다

     패킷이 IP_FW_F_PRN 비트가 세트 되고 있는 룰에 적합해, IPFIREWALL_VERBOSE 가 유효하게 되고 있는 경우에는
     메세지가 콘솔에 출력됩니다.  IPFIREWALL_VERBOSE_LIMIT 는 각각의 룰이 로그 메세지를 출력할 수 있다 회수의
     최대치를 제한합니다.  이러한 변수도 sysctl(3) 인터페이스를 경유해 이용할 수 있습니다.

진단
     [EINVAL]  IP 옵션의 란이 최소치보다 짧은지, 제공된 옵션
               버퍼보다 길고 부적절한 형식이었습니다. ip_fw 구조체로 구조적
               에러가 발생했습니다 (n_src_p+n_dst_p 과대, ALL/ICMP
               프로토콜을 위한 포트 세트 등). 부정한 룰 번호가
               사용되었습니다.

관련 항목
     setsockopt(2), divert(4), ip(4), ipfw(8), sysctl(8)

버그
     ``tee''룰은 아직 실장되고 있지 않습니다 (현재는 효과가 없습니다).

     이 man 페이지는 아직 작업이 필요합니다.

역사
     ipfw 기능은 최초로 BSDI 에의 패키지로서 Daniel Boulet <danny@BouletFermat.ab.ca> 에 의해
     쓰여졌습니다.  Ugen J.S.Antsilevich <ugen@NetVision.net.il> 하지만 큰폭으로 변경해, FreeBSD
     에 이식했습니다.

     Archie Cobbs <archie@whistle.com> 에 달려 있고 구두인가의 확장이 더해졌습니다.