FreeBSD 11.1R のカーネルでは、各通信 domain に関する情報はチェーン状に繋がれた domain 構造体で管理されています。domain 構造体は sys/sys/domain.h で宣言されています。
チェーンの先頭は domain 構造体へのポインタ domains で、sys/kern/uipc_domain.c で大域変数として定義されています。
各通信 domain で利用できるプロトコルに関する情報は protosw 構造体で管理されています。protosw 構造体は sys/sys/protosw.h で宣言されています。
各通信 domain ごとに利用可能な protosw 構造体は、配列として定義されています。domain 構造体のメンバーには、protosw 構造体の配列の先頭へのポインタ dom_protosw と、配列の終了アドレスへのポインタ dom_protoswNPROTOSW があります。これにより各通信 domain ごとにプロトコルを検索できるようになっています。
以下、domain 構造体と protosw 構造体の検索方法についてです。
指定された family に対応する domain 構造体を検索する関数は pffinddomain() です。domain 構造体のチェーンを辿って、指定された family と同じ family の domain 構造体を見つけたら、そのアドレスを返す簡単な関数です。
指定された family と type に対応する protosw 構造体を検索する関数は pffindtype() です。まず pffinddomain() を呼び出して、指定された family に対応する domain 構造体を探します。見つかった場合は、その domain 構造体から指された protosw 構造体の配列の中から、指定された type と同じ type の protosw 構造体を探して、最初に見つかった protosw 構造体を返します。
指定された family と type と protocol に対応する protosw 構造体を検索する関数は pffindproto() です。まず pffinddomain() を呼び出して、指定された family に対応する domain 構造体を探します。見つかった場合は、その domain 構造体から指された protosw 構造体の配列の中から、指定された type 及び protocol と同じ type 及び protocol の protosw 構造体を探して、見つかった protosw 構造体を返します。type として SOCK_RAW が指定された場合は『+α』の検索条件が入ります。
カーネル内で domain 構造体や protosw 構造体を探すときは、これら3つの関数が必要に応じて呼び出されます。いずれも sys/kern/uipc_domain.c で定義されています。