TCP/UDPソケットを扱ってきましたが、rawソケットを使用することで、下記3種類の機能を利用出来ます。
1. rawソケットを利用することで、ICMPv4、ICMPv6、IGMPパケットの送受信が可能となる。
Pingは、ICMPエコー要求を送信し、ICMPエコー応答を受信する。加えて、マルチキャスト経路デーモンmroutedは
IGMPv4パケットの送受信を行う。
2. カーネルが処理しないIPv4プロトコルフィールドをプロセスから読み書き出来る。
3. プロセスは、IP_HDRINCLソケットオプションを利用して、独自のIPv4ヘッダを作成することが出来る。
rawソケットの一連の記事は、ひとまずpingプログラムの動作の理解を目処に記載していくことにします。
いちおー、ipアドレスの偽装などもrawソケットを利用すれば出来るのですが、これを記事にするかどうかはもう少し考えます。
個人事業主だし、商売に差し障りがあったら困るしなぁ。
今回は、軽くrawソケットの作成まで。
rawソケットの作成
下記の手順で、rawソケットを作成します。
1. socket関数の第二引数にSOCK_RAWを指定し、rawソケットを作成する。
IPv4のrawソケットを作成するには、次のコードを用いる。
int sockfd;
sockfd = socket(AF_INET, SOCK_RAW, protocol);
protocolは、<netinet/in.h>で定義されているIPPROTO_XXX定数の一つ。
2. IP_HDRINCLソケットオプションを設定することが出来る。
const int on = 1;
if(setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0)
このオプションの効果については、次の記事に記載します。
3. rawソケットに対して、bindを呼び出す事が出来るが、まれ。
rawソケットにはポート番号の概念が存在しない。
bindを呼び出すことで、rawソケットから送信されるデータグラムに始点IPアドレスを設定出来る。
4. rawソケットに対して、connectを呼び出すことが出来るがこれもまれ。
connectを呼び出す事で、終点IPアドレスを設定出来る。