Linuxカーネルでは、TCP、UDPなどと同様に、トランスポート層に独自のプロトコルを追加できることを知っています.
アプリケーションにパケットを転送できるIP、ARPに似たネットワーク層で新しいプロトコルを登録するためのフックはありますか?また、このプロトコルをLinuxカーネルに追加する方法はありますか?
Linuxカーネルでは、TCP、UDPなどと同様に、トランスポート層に独自のプロトコルを追加できることを知っています.
アプリケーションにパケットを転送できるIP、ARPに似たネットワーク層で新しいプロトコルを登録するためのフックはありますか?また、このプロトコルをLinuxカーネルに追加する方法はありますか?
ユーザースペースからプロトコルへの通信を処理するには、プロトコルをカーネルソケットAPIに登録します。これにより、ユーザースペースから通常のソケットを作成できます。
関連するコードサンプルについては、Bluetooth/RFCOMソケットの実装をご覧ください。
static const struct proto_ops rfcomm_sock_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.bind = rfcomm_sock_bind,
.connect = rfcomm_sock_connect,
.listen = rfcomm_sock_listen,
.
.
.
.accept = rfcomm_sock_accept,
};
static const struct net_proto_family rfcomm_sock_family_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.create = rfcomm_sock_create
};
プロトコルを登録するには、proto_ops構造体に入力する必要があります。この構造は、カーネル内の他の場所で観察されるオブジェクト指向パターンに従います。この構造は、独自のソケットインターフェイスを実装する開発者が従うべきインターフェイスを定義します。
バインド、接続、リッスン、構造体エントリへの関数ポインタの割り当てなど、インターフェイスで定義されている関数を実装します。オペレーションインターフェイスでカバーされていない機能のioctlを定義します。
最終的には、create関数から返すsocket構造体に後で埋め込む構造体になります。
Struct net_proto_familyは、新しいプロトコルファミリを定義します。この構造体には、関数の実装がproto_ops構造体で満たされたソケット構造体を設定する必要があるcreate関数が含まれています。
その後、ファミリをsock_registerに登録します。すべて問題がなければ、ユーザースペースから適切なソケットを作成できるはずです。
内部的には、プロトコルはおそらくskbuffs(こことここを参照)を使用してネットワークデバイスと通信する必要があります。
skbuffsは、Linuxカーネルでネットワークパケットを処理するための普遍的な方法です。パケットはネットワークカードによって受信され、いくつかのskbuffに入れられてから、ネットワークスタックに渡されます。ネットワークスタックは常にskbuffを使用します。
これは、Linuxカーネル内にネットワークプロトコルを実装するための基本的なデータ構造とIOパスです。
この手順を最初から最後まで説明しているドキュメントを知りません。ソースはこれであなたと一緒です。
プロトコルを実装するには、カーネル モジュールを記述します。
モジュールは で新しいデバイスを作成する必要があります/dev
。その後、アプリケーションはioctl()
モジュールと対話して、ターゲット ホスト、オプションなどを指定できます。
カーネル モジュールに実装する方法の詳細については、The Linux Kernel Module Programming Guide の第 7 章ioctl()
を参照してください。
このブログ投稿も、このトピックの良い紹介のようです。