C言語 整数のIPからドット表記のIPアドレスの文字列を取得する方法
スポンサーリンク
このドキュメントの内容は、以下の通りです。
- はじめに
- 整数のIPからドット区切りのIPアドレスの文字列を取得する方法
- inet_ntoaのプロトタイプ
- inet_ntoa のサンプルプログラム
- コンパイル方法
- 実行例
- inet_ntoaの実装
- まとめ
はじめに
インターネットでは、TCP/IPと呼ばれるプロトコルが使われています。TCP/IPなくして、インターネットは成り立ちません。TCP/IPのIPとは Internet Protocolの略です。インターネットでは、IPアドレスを利用して通信が行われます。パソコンが通信をするときには、IPアドレスがふられています。家にあるルータにもIPアドレスがわりふられています。
IPアドレスは、人がわかりやすいように、ドット区切りの表記をします。コンピュータの内部では、IPアドレスは、ドット区切りの表記と整数の値の表現を変換して使われていたりします。
多くの方は、あまりIPアドレスを直接見たり、指定したりすることはないと思います。ほとんどの方は、DNSと呼ばれる仕組みを利用していて、IPアドレスが隠蔽されているからです。
現在利用されている IPには、IP バージョン4 (IPv4) と IP バージョン 6 (IPv6)があります。
IPv4のIPアドレスは32ビットであるため、1つの整数で表現されます。
コンピュータの内部で整数のIPアドレスを扱っているときに、人が見てわかりやすいように、ドット区切りの表記のIPアドレスに変換したいことがあるかと思います。ここでは、C言語で整数のIPアドレスをドット区切りのIPアドレスに変換する方法について解説します。
整数のIPからドット区切りのIPアドレスの文字列を取得する方法
C言語で整数のIPアドレスからドット表記のIPアドレス(192.168.0.1みたいなの)の文字列を取得する方法を説明します。ソケットプログラミングで利用される型のひとつに in_addr_t と呼ばれるものがあります。in_addr_t には、インターネットアドレス、つまりIPアドレスを格納するための変数になります。
ソケットプログラミングで利用されるライブラリの関数の中に、整数のアドレスと文字列のアドレスを変換する関数があります。
ところが、in_addr_t のIPを直接受け取ってくれるinet系の関数がないので in_addr構造体を利用します。in_addr構造体の中身は、in_addr_t だけです。
inet_ntoaのかわりにinet_ntoa_rを使うこともできます。 inet_ntoa_rはinet_ntoaの再入可能(reentrant)バージョンです。
inet_ntoa や inet_aton は、static のバッファを使っていることや IPv6 をサポートしていないため、 inet_ntop や inet_pton を利用したほうが良いでしょう。
inet_ntoaのプロトタイプ
/usr/include/netinet/in.h のヘッダファイルに、以下の関数が定義されています。
char * inet_ntoa(struct in_addr in); char * inet_ntoa_r(struct in_addr in, char *buf, socklen_t size);
inet_ntoa のサンプルプログラム
正の整数のIPアドレスを変換するサンプルプログラムを以下に示します。
#include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> int main(int argc, char *argv[]) { unsigned long long_addr = 2085852108ul; struct in_addr inaddr = { htonl(long_addr) }; char *addrstr = inet_ntoa(inaddr); if (addrstr) { printf ("%s\n", addrstr); } else { // can not get address } return 0; }
inet_ntoa() を見て、気づいたかもしれませんが、 char*型のポインタが返されます。つまり、 inet_ntoa のローカルの static なバッファのアドレスが返されています。inet_ntoa を呼び出したあとに、ほかのアドレスを指定して inet_ntoa を呼び出すと、inet_ntoaのローカルのstatic変数が上書きされてしまいますので、複数回呼び出すときは、注意して利用する必要があります。
コンパイル方法
サンプルプログラムをコンパイルする方法は以下の通りです。% cc socket.c
実行例
以下がサンプルプログラムの実行例です。% ./a.out 124.83.147.204
inet_ntoaの実装
inet_ntoa は、 FreeBSD では、 /usr/src/lib/libc/inet/inet_ntoa.c で実装されています。
inet_ntoa は、static なローカル変数にIPアドレスの文字列が格納されて返ってきます。そのため、inet_ntoaを複数回連続して呼び出すような使い方をする場合には、使い方に注意が必要です。マルチスレッドで呼び出すと、おかしなことになるので、使ってはいけません。
inet_ntoa_r は、バッファを渡して、その中に、結果が入ってくるので、複数の呼び出すをする場合にも問題はありません。マルチスレッドでも問題ありません。
inet_ntoa と inet_ntoa_r はともに、 inet_ntop を呼び出します。
inet_ntop は、 FreeBSD では、 /usr/src/lib/libc/inet/inet_ntop.c で実装されています。
inet_ntop 内部では、第1引数のアドレスファミリの指定によって、inet_ntop4やinet_ntop6 が呼び分けられます。
inet_ntop4 は、snprintf で変換しています。
static const char fmt[] = "%u.%u.%u.%u"; char tmp[sizeof "255.255.255.255"]; int l; l = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]);
テンポラリのバッファに変換して、最後に strlcpy で指定したバッファに書き込みなおしてます。
テンポラリのバッファの確保のコードは以下のコードです。
char tmp[sizeof "255.255.255.255"];
inet_ntop6 の実装は、 inet_ntop4 に比べるとやや複雑な実装になっています。しかも内部で inet_ntop4 を呼び出していた李します。
もし興味があれば、よく読んでみてください。
まとめ
IPv4 / IPv6 時代では、inet_ntop を利用しましょう。
inet_ntoa は、static なバッファを利用するため、おすすめできません。
inet_ntop のサンプルコードは [2008-11-16-1] をご覧ください。
スポンサーリンク
スポンサーリンク
いつもシェア、ありがとうございます!
もっと情報を探しませんか?
関連記事
最近の記事
- パナソニック ジェットウォッシャードルツ EW-DJ61-Wのホースの修理
- LinuxセキュリティモジュールIntegrity Policy Enforcement
- アマゾンのEcho Show 5を買ったのでレビューします
- アマゾンのサイバーマンデーはAlexa Echo Show 5が安い
- Android スマートフォン OnePlus 7T と OnePlus 7の違い
- Android スマートフォン OnePlus 7 をAndroid10にアップデートしてみた
- クレジットカードのバーチャルカードの比較のまとめ
- 活動量計 Xiaomi Mi Band 4を買ってみたのでレビュー
- Android スマートフォン OnePlus 7 のレビュー
- AliExpressでスマートフォンを買い物してみた
- パソコンのホコリ対策 レンジフードフィルターと養生テープ
- 80PLUS GOLDのPC電源ユニットAntec NeoEco 750 Goldのレビュー
- イギリスの付加価値税 VAT は払い戻しを受けられる
- イギリスのロンドンでスーツケースなど荷物を預けられる場所は
- イギリスのロンドンで地下鉄やバスに乗るならオイスターカードを使おう
- イギリスのヒースロー空港からロンドン市内への行き方
- 航空便でほかの航空会社に乗り継ぎがある場合のオンラインチェックイン
- SFC会員がANA便ではなくベトナム航空のコードシェアを試して解ったこと
- ベトナムの入国審査でeチケットの掲示が必要だった話
- シアトルの交通ICカードはオルカカード(Orca)です
人気のページ
- Windows7 IME 辞書ツールで単語の登録に失敗しました
- C言語 popen()でコマンドを実行して出力を読み込む
- Windows7で休止状態にする方法
- CentOS MySQLの起動、停止、再起動
- loggerコマンドでsyslogにエラーを出力する方法
- パソコンパーツの買取をしてくれる店のまとめ
- Java Mapの使い方 get(),put(),remove(),size(),clear()
- 楽天のRポイントカードを作ってみた
- iPhone 5 から iPhone 6 に乗り換えたのでレビュー
- netstatコマンドのステータスの意味
スポンサーリンク
過去ログ
2020 : 01 02 03 04 05 06 07 08 09 10 11 122019 : 01 02 03 04 05 06 07 08 09 10 11 12
2018 : 01 02 03 04 05 06 07 08 09 10 11 12
2017 : 01 02 03 04 05 06 07 08 09 10 11 12
2016 : 01 02 03 04 05 06 07 08 09 10 11 12
2015 : 01 02 03 04 05 06 07 08 09 10 11 12
2014 : 01 02 03 04 05 06 07 08 09 10 11 12
2013 : 01 02 03 04 05 06 07 08 09 10 11 12
2012 : 01 02 03 04 05 06 07 08 09 10 11 12
2011 : 01 02 03 04 05 06 07 08 09 10 11 12
2010 : 01 02 03 04 05 06 07 08 09 10 11 12
2009 : 01 02 03 04 05 06 07 08 09 10 11 12
2008 : 01 02 03 04 05 06 07 08 09 10 11 12
2007 : 01 02 03 04 05 06 07 08 09 10 11 12
2006 : 01 02 03 04 05 06 07 08 09 10 11 12
2005 : 01 02 03 04 05 06 07 08 09 10 11 12
2004 : 01 02 03 04 05 06 07 08 09 10 11 12
2003 : 01 02 03 04 05 06 07 08 09 10 11 12