#include <arpa/inet.h> int inet_net_pton(int af, const char *pres, void *netp, size_t nsize); char *inet_net_ntop(int af, const void *netp, int bits, char *pres, size_t psize);
-lresolv でリンクする。
glibc 向けの機能検査マクロの要件 (feature_test_macros(7) 参照):
inet_net_pton(), inet_net_ntop():
どちらの関数でも af は変換を行うアドレスファミリーを指定する。 サポートされている値は AF_INET だけである。
成功すると inet_net_pton() は netp に格納した結果のネットワーク番号フィールドのビット数を返す。 入力の表記形式と返り値に関する議論は「注意」の節を参照。
注意: netp が指すバッファーは inet_net_pton() の呼び出し前に 0 で埋めるべきである。 呼び出しではネットワーク番号で必要なバイトだけが書き込まれ、 そのバイト数は完全なネットワークアドレスのバイト数よりも少ないこともある。
NULL 終端された表記形式の文字列は pres が指すバッファーに格納される。 psize 引数は pres で利用可能なバイト数を指定する。 表記形式は CIDR 形式、 つまり、 ネットワークアドレスを表すドット区切りの 10 進数に、 スラッシュとネットワーク番号のビットサイズが続く形式である。
成功すると inet_net_ntop() は pres を返す。 エラーの場合、 NULL を返し、 errno にエラーを示す値がセットされる。
先頭に "0x" か "0X" がある場合 16 進数値となる。 16 進数はネットワークバイトオーダーの左から右へ半オクテット (4 ビット) ずつ順番に埋められる。
ドット区切りの 10 進数表記では、 最大 4 つのオクテットをドット区切りの 10 進数で指定する。 したがって、 以下の形式を指定できる。
a.b.c.d
a.b.c
a.b
a
各部分は 0 から 255 の範囲の数字で、ネットワーク番号の各バイトに左から右にネットワークバイトオーダー (ビッグエンディアン) で順番に埋められる。 省略された部分があれば、 対応するネットワーク番号のバイトは 0 となる。
16 進数とドット区切りの 10 進数形式のどちらの場合も、 ネットワーク番号の後ろにスラッシュと 0 から 32 の範囲の数字をオプションで付けることができる。 この数字はネットワーク番号のビット単位のサイズを示すものである。
上記の手順から得られる bits の値が 8 以上だが、 ネットワーク番号で指定されたオクテット数が bits/8 より大きい場合、 bits には実際に指定されたオクテット数を 8 倍した値が設定される。
inet_net_pton() が netp 引数のすべてのバイトに書き込むわけではないことを示すため、 プログラムにはオプションで 2 番目のコマンドライン引数を指定することができ、 その引数の数字を使って inet_net_pton() を呼び出す前にバッファーを初期化する。 出力の最終行として、 ユーザーがどのバイトが inet_net_pton() によって変更されなかったかを確認できるように、 プログラムは inet_net_pton() が返したバッファーの全バイトを表示する。
この実行例では、 inet_net_pton() が推測したネットワーク番号のビット数を表示する。
$ ./a.out 193.168 inet_net_pton() returned: 24 inet_net_ntop() yielded: 193.168.0/24 Raw address: c1a80000
inet_net_pton() が結果のバッファーの未使用バイトを 0 埋めしないことを確認する。
$ ./a.out 193.168 0xffffffff inet_net_pton() returned: 24 inet_net_ntop() yielded: 193.168.0/24 Raw address: c1a800ff
表記形式の文字列で渡されたバイト数が推測した値より大きい場合、 inet_net_pton() が推測するネットワーク番号のサイズを広げることを確認する。
$ ./a.out 193.168.1.128 inet_net_pton() returned: 32 inet_net_ntop() yielded: 193.168.1.128/32 Raw address: c1a80180
ネットワーク番号のサイズが明示的に指定すると、推測されるネットワーク番号のサイズが上書きされる (ただし、 明示的に指定された残りのバイトは inet_net_pton() で使用され、結果のバッファーに書き込まれる)。
$ ./a.out 193.168.1.128/24 inet_net_pton() returned: 24 inet_net_ntop() yielded: 193.168.1/24 Raw address: c1a80180
#include <arpa/inet.h> #include <stdio.h> #include <stdlib.h>
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
int
main(int argc, char *argv[])
{
char buf[100];
struct in_addr addr;
int bits;
if (argc < 2) {
fprintf(stderr,
"Usage: %s presentation-form [addr-init-value]\n",
argv[0]);
exit(EXIT_FAILURE);
}
/* argv[2] (数値) が指定されると、その数字を使って inet_net_pton()
に渡す出力バッファーを初期化する。これにより inet_net_pton() が
ネットワーク番号に必要なバイトだけを書き込むことを確認できるよう
にする。 argv[2] が指定されなかった場合、バッファーは 0 で初期化
する (これが推奨される方法である)。 */
addr.s_addr = (argc > 2) ? strtod(argv[2], NULL) : 0;
/* argv[1] の表記形式のネットワーク番号をバイナリー形式に変換する */
bits = inet_net_pton(AF_INET, argv[1], &addr, sizeof(addr));
if (bits == -1)
errExit("inet_net_ntop");
printf("inet_net_pton() returned: %d\n", bits);
/* inet_net_pton() が返した 'bits' を使って、
バイナリー形式を表記形式に変換する */
if (inet_net_ntop(AF_INET, &addr, bits, buf, sizeof(buf)) == NULL)
errExit("inet_net_ntop");
printf("inet_net_ntop() yielded: %s\n", buf);
/* 'addr' を名前の形で (ネットワークバイトオーダーで) 表示する。
これにより inet_net_ntop() が表示しないバイトを確認できる。
これらのバイトの一部は inet_net_ntop() では変更されない場合があり、
その場合 argv[2] で指定された初期値のままになる。 */
printf("Raw address: %x\n", htonl(addr.s_addr));