EN JA
SEND(4)
SEND(4) FreeBSD Kernel Interfaces Manual SEND(4)

名称

sendSecure Neighbor Discovery (SeND) のためのカーネルサイドサポート

書式

#include < sys/socket.h>
#include < netinet/in.h>
#include < netinet6/send.h>

int
socket( PF_INET6, SOCK_RAW, IPPROTO_SEND);

ブート時にモジュールとしてドライバをロードするためには、次の行を loader.conf(5) に置きます:

send_load="YES"

解説

IPv6 ノードは、リンク上の他のノードを発見して、ルータを見つけてそれらのリンクレイヤアドレスを決定し、アクティブなメンバへのパスに関する到達可能性の情報を保守するために Neighbor Discovery Protocol (NDP) を使用します。 NDP は、様々な攻撃を受けやすいです [RFC3756]。 Secure Neighbor Discovery は、NDP への脅威に対抗する NDP への 1 組の拡張です [RFC3971]。

SeND のためのカーネルサイドのサポートは、 NDP スタックから関連パケット (Neighbor Solicitations、Neighbor Advertisements、Router Solicitations、 Router Advertisements と Redirects) を配信し、専用のソケットでユーザ空間にそれらを送り、更なる処理のためにそれらを再注入して戻すフックがあるカーネルモージュールから成ります。フックは、 send モジュールがロードされる場合のみ、トリガされます。

ネイティブの SeND ソケットは、生の IP ソケットと同様ですが、それ自体、内部の疑似プロトコル (IPPROTO_SEND) があります。 struct sockaddr_send は、 < netinet6/send.h> に定義されています。それは、構造体の合計長、アドレスファミリ、インタフェースの観点からのパケットの着信または発信方向とインタフェースインデックスを定義しています。

struct sockaddr_send { 
        unsigned char           send_len;       /* 合計長 */ 
        sa_family_t             send_family;    /* アドレスファミリ */ 
        int                     send_direction; 
        int                     send_ifidx; 
        char                    send_zero[8]; 
};

アドレスファミリは、常に AF_INET6 です。 send_direction 変数は、インタフェースの観点からパケットの方向を示し、値 SND_IN または SND_OUT のいずれかがあります。 send_ifidx 変数は、受信または送信インタフェースのインタフェースインデックスです。 send_zero 変数は、詰め物であり、常に 0 でなければなりません。

ユーザ空間のアプリケーションがソケットを送信するために接続された場合、通常、まるでモジュールがロードされなかったかのように、処理は、継続します。

入力フック

入力フックは、ユーザ空間に nd6 スタックを通して、ワイヤからの途中で、着信または発信 NDP パケットの入力パスにちなんで名前が付けられます。関連パケットは、 send モジュールがロードされるなら、mbuf_tag ( mbuf_tags(9) 参照) を mbuf(9) に追加することによって識別されます。次に、それは、SeND アプリケーションによって暗号の保護または検証のいずれかのためにカーネルユーザランドインタフェースに渡されます。フックは、着信と発信パケットの両方の場合に、パケットの方向を表す引数を取ります。 SND_IN は、通常、SeND オプションによって保護される着信パケットの方向で、次に、暗号の検証のためにユーザ空間に送られます。 SND_OUT は、発信の方向です。それは、SeND オプションの追加のためにユーザ空間に送られる応答と局所的に起こる発信パケットの両方について説明しています。

着信パケット

ワイヤからの着信 ND パケット:

                                        kernelspace ( userspace 
                                                    ) 
 incoming SeND/ND packet                            ( 
            |                                       ) 
            v                 ( SND_IN )            ( 
           icmp6_input() -> send_input_hook ---> send socket ----+ 
            :                                       )            | 
            :             #                 #       (            | 
   normal   :             #                 #       )            v 
 processing :             #     send.ko     #       (    SeND application 
    path    :             #                 #       )            | 
            :             #                 #       (            | 
            v                                       )            | 
   icmp6/nd6_??_input() <- protocol switch  <--- send socket <---+ 
            |         structure (IPPPROTO_SEND)     ) 
            |                ( SND_IN )             ( 
            v                                       ) 
 通常の ND 処理を続行                               (

発信パケット

(応答または局所的にトリガされた) 発信 ND パケット:

                                        kernelspace ( userspace 
                                                    ) 
 nd6_na_input()                                     ( 
 +PACKET_TAG_ND_OUTGOING                            ) 
 |                                                  ) 
 |   outgoing packet                                ( 
 |          |                                       ) 
 |          v                                       ( 
 |   icmp6_redirect_output()                        ) 
 |   nd6_ns_output()                                ( 
 |   nd6_na_output()                                ) 
 |   +PACKET_TAG_ND_OUTGOING                        ( 
 |          |                                       ) 
 |          +-----------<- rip6_output() <----------)----- rtsol/rtadvd/.. 
 |          |              +PACKET_TAG_ND_OUTGOING  ( 
 |          v                                       ) 
 |       ip6_output()                               ( 
 |          |                                       ) 
 +-------->-+                                       ( 
            |                                       ) 
            v                ( SND_OUT )            ( 
        nd6_output_lle() -> send_input_hook ---> send socket ----+ 
 -PACKET_TAG_ND_OUTGOING                            )            | 
            :             #                 #       (            | 
   normal   :             #                 #       )            v 
 processing :             #     send.ko     #       (    SeND application 
    path    :             #                 #       )            | 
            :             #                 #       (            | 
            v                                       )            | 
    (*ifp->if_output)() <- protocol switch  <--- send socket <---+ 
            |         structure (IPPPROTO_SEND)     ) 
            |                ( SND_OUT )            ( 
            v                                       ) 
 通常のパケット出力を続行                           (

エラー

ソケット操作は、返された次のエラー 1 つで失敗するかもしれません:
[ EEXIST]
別のユーザ空間の SeND アプリケーションは、ソケットにバインドさます。
[ ENOBUFS]
SeND アプリケーションから着信 (SeND 保護された) または発信 (SeND 有効にされた) パケットを受信する空間の記憶域。
[ ENOSYS]
ユーザ空間から受信され、更なる処理のために NDP スタックに渡されたパケットが、Neighbor Solicitation、Neighbor Advertisement、 Router Solicitation、Router Advertisement または Redirect でもありません。
[ ENOENT]
インタフェース出力ルーチンがインタフェースのパケットの送信で失敗するなら、起こります。

歴史

send モジュールは、 FreeBSD 9.0 ではじめて登場しました。

作者

Ana Kukec <anchie@FreeBSD.org>, University of Zagreb

バグ

NDP ロックの不足のために、 send モジュールをアンロードすることは、現在、不可能です。
September 19, 2010 FreeBSD