FreeBSDのrawソケットを使うときに困ったこと

FreeBSDでraw socketを利用する際、setsockoptでIP_HDRINCLオプションを指定すれば、IPヘッダも自由に作ることができる。
詰まったのは、自分で作ったパケットをsendtoするときである。sendtoでInvalid argumentと言われて、何故か送信できない。じっくりヘッダ作成ルーチンを見直すが、変な値をセットしているところはない。バイトオーダーもちゃんとネットワークバイトオーダーになっている。どうしようもなくスティーブンスのUNIXネットワークプログラミングVol.1のraw socket関連のページを見直していると、25.3節でIP_HDRINCLオプションに関して次のように書いてあった。

Berkley派生のカーネルでは、ip_lenとip_offフィールドがホストバイト順序であることを除き、すべてのフィールドがネットワークバイト順序である。

つまりバイトオーダーが違ったのだ。なんだそりゃ。ip_lenのhtonsを取り払って、再コンパイル&実行するとあっさり送信完了。やれやれだ。