以下のコードに、
HP-UX
にIPv6
が実装されているかどうかをアプリケーションがプログラム で判定する方法を示します。アプリケーションは、コンパイル時や実行時に/dev/ip6デバイス ファイルの存在をチェックして、システムにIPv6 API
およびIPv6
スタックがあるかどうかを 判定することができます。/dev/ip6が存在しない場合、アプリケーションはIPv4 API
を使い 続けます。if ((fd = open("dev/ip6", O_RDWR)) == -1) /*
* /dev/ip6 failed to open., Therefore the IPv6 product
* is not installed on the system. An application should use the * existing IPv4 code.
*/
...
else
/*
* dev/ip6 exists, so the IPv6 product is probably installed.
* IPv6 APIs can handle both IPv4 and IPv6 traffic */
注記
HP-UX 11i v2
からは、IPv6
が自動的にHP-UX
に組み込まれます。IPv6インストールの検証
第
14
章 6215 クライアント / サーバー サンプル プログラ ム
以下で示すコードは、
HP-UX 11i v2
の/usr/lib/demos/networking/socketディレクトリに 格納されているものと同じIPv4
クライアント/
サーバーサンプルプログラムをベースにしてい ます。クライアントは、exampleというサービスを要求します。クライアントの/etc/servicesファ イルに、example用のエントリーを追加してください。exampleサービス用のポートアドレス
として、
22375
などの未使用のポート番号を割り当ててください。サーバーを実行するホストでも、/etc/servicesファイル内のexampleに、同じポート番号を割り当てておかなければなり ません。
クライアント/サーバーサンプルプログラム
IPv4 TCP
クライアントのコード第
15
章 64IPv4 TCP クライアントのコード
以下のコードは、
HP-UX
の/usr/lib/demos/networking/socketディレクトリに格納されて いるものと同じIPv4
クライアントプログラムの一部です。クライアントは、
“
example”
というサービスを要求します。/etc/servicesファイルに“
example”
用のエントリーを追加してください。“
example”
サービス用のポートアドレスとして、22375
などの未使用のポート番号を割り当ててください。サーバーを実行するホストでも、/etc/servicesファイル内の
“
example”
に、同じポート番号を割り当てておかなければなりま せん。struct sockaddr_in peeraddr_in; /* for peer socket address */
memset ((char *)&peeraddr_in, 0, sizeof(struct sockaddr_in));
hp = gethostbyname (argv[1]);
if (hp == NULL) {
fprintf(stderr, "%s: %s not found in /etc/hosts\n", argv[0], argv[1]);
exit(1);
}
peeraddr_in.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
/* Find the information for the "example" server * in order to get the needed port number.
*/
sp = getservbyname ("example", "tcp");
if (sp == NULL) {
fprintf(stderr, "%s: example not found in /etc/services\n argv[0]);
exit(1);
}
peeraddr_in.sin_port = sp->s_port;
/* Create the socket. */
s = socket (AF_INET, SOCK_STREAM, 0);
if (s == -1) {
perror(argv[0]);
fprintf(stderr, "%s: unable to create socket\n", argv[0]);
exit(1);
}
/* Try to connect to the remote server at the address put in peeraddr.
*/
if (connect(s, &peeraddr_in, sizeof(struct sockaddr_in)) == -1{
クライアント/サーバーサンプルプログラム
IPv4 TCP
クライアントのコードperror(argv[0]);
fprintf(stderr, "%s: unable to connect to remote\n", argv[0]);
exit(1);
}
クライアント/サーバーサンプルプログラム
getipnodebyname()
を使用するIPv6 TCP
クライアント第
15
章 66getipnodebyname() を使用する IPv6 TCP クライアント
以下のコードは、
HP-UX 11i v2
の/usr/lib/demos/networking/socket/af_inet6ディレク トリに格納されているIPv6
クライアントサンプルプログラムの一部を、getipnodebyname() 関数呼び出しを使用するように書き換えたものです。struct sockaddr_in6 peeraddr_in6; /* for peer socket address */
memset ((char *)&peeraddr_in6, 0, sizeof(struct sockaddr_in6));
hp = getipnodebyname (argv[1], AF_INET6, AI_DEFAULT, &error);
if (hp == NULL) {
fprintf(stderr, "%s: %s not found in /etc/hosts\n", argv[0], argv[1]);
exit(1);
}
peeraddr_in6.sin6_family = hp->h_addrtype;
memcpy(&peeraddr_in6.sin6_addr, hp->h_addr, hp->h_length);
/* Find the information for the "example" server * in order to get the needed port number.
*/
sp = getservbyname ("example", "tcp");
if (sp == NULL) {
fprintf(stderr, "%s: example not found in /etc/services\n", argv[0]);
exit(1);
}
peeraddr_in6.sin6_port = sp->s_port;
/* Create the socket. */
s = socket (AF_INET6, SOCK_STREAM, 0);
if (s == -1) {
perror(argv[0]);
fprintf(stderr, "%s: unable to create socket\n", argv[0]);
exit(1);
}
/* Try to connect to the remote server at the address * which was just built into peeraddr.
*/
if (connect(s, &peeraddr_in6, sizeof(peeraddr_in6)) == -1) { perror(argv[0]);
fprintf(stderr, "%s: unable to connect to remote\n", argv[0]);
exit(1);
}
クライアント/サーバーサンプルプログラム ネーム
/
サービスの検索にgetaddrinfo()
を使用するIPv6 TCP
クライアントネーム / サービスの検索に getaddrinfo() を使用する IPv6 TCP クラ イアント
この
IPv6 TCP
クライアントのコードは、前出のIPv6
クライアントのコードの一部ですが、gethostbyname()ではなくgetaddrinfo()を使用しています。
struct addrinfo *res, *ainfo;
struct addrinfo hints;
/* clear out hints */
memset ((char *)&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo(argv[1], "example", &hints, &res);
if (error != 0) {
fprintf(stderr, "%s: %s not found in name service database\n", argv[0], argv[1]);
exit(1);
}
for (ainfo = res; ainfo != NULL; ainfo = ainfo->ai_next) { /* Create the socket. */
s = socket (ainfo->ai_family,ainfo->ai_socktype, ainfo->ai_protocol);
if (s == -1) {
perror(argv[0]);
fprintf(stderr, "%s: unable to create socket\n", argv[0]);
freeaddrinfo(res);
exit(1);
}
if (connect(s, ainfo->ai_addr, ainfo->ai_addrlen) == -1) { perror(argv[0]);
fprintf(stderr, "%s: unable to connect to remote\n", argv[0]);
close(s);
continue;
} else
break;
クライアント/サーバーサンプルプログラム
IPv4 TCP
サーバーコード第
15
章 68IPv4 TCP サーバー コード
以下のコードは、
HP-UX 11i v2
の/usr/lib/demos/networking/socketディレクトリに格納 されているものと同じIPv4
サーバープログラム例の一部です。struct sockaddr_in6 peeraddr_in6; /* for peer socket address */
sp = getservbyname ("example", "tcp");
if (sp == NULL) {
fprintf(stderr, "%s: example not found in /etc/services\n",argv[0]);
exit(1);
}
myaddr_in.sin_port = sp->s_port;
/* Create the listen socket. */
ls = socket (AF_INET, SOCK_STREAM, 0);
if (ls == -1) {
perror(argv[0]);
fprintf(stderr, "%s: unable to create socket\n", argv[0]);
exit(1);
}
/* Bind the listen address to the socket. */
if (bind(ls, &myaddr_in, sizeof(struct sockaddr_in)) == -1) { perror(argv[0]);
fprintf(stderr, "%s: unable to bind address\n", argv[0]);
exit(1);
}
/* Initiate the listen on the socket so remote users * can connect. The listen backlog is set to 5, which * is within the supported range of 1 to 20.
*/
if (listen(ls, 5) == -1) { perror(argv[0]);
fprintf(stderr, "%s: unable to listen on socket\n", argv[0]);
exit(1);
}
クライアント/サーバーサンプルプログラム サービスアドレスの検索に
getaddrinfo()
を使用するIPv6 TCP
サーバーサービス アドレスの検索に getaddrinfo() を使用する IPv6 TCP サー バー
以下のコードは、
HP-UX 11i v2
の/usr/lib/demos/networking/socket/af_inet6ディレク トリに格納されているIPv6
サーバーサンプルプログラムの一部を、getaddrinfo()関数呼び 出しを使用するように書き換えたものです。struct addrinfo *ainfo, *res;
struct addrinfo hints;
/* zero-out the hints before assignment */
memset (&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
hints.ai_flags = AI_PASSIVE;
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo(NULL, "example", &hints, &res);
if (error != 0) {
fprintf(stderr, "%s: %s for service 'example'\n", argv[0], gai_strerror(error));
exit(1);
}
/* Create the listen socket. */
ls = socket (res->ai_family, res->ai_socktype, res->ai_protocol);
if (ls == -1) {
perror(argv[0]);
fprintf(stderr, "%s: unable to create socket\n", argv[0]);
exit(1);
}
/* Bind the listen address to the socket. */
if (bind(ls, res->ai_addr, res->ai_addrlen) == -1) { perror(argv[0]);
fprintf(stderr, "%s: unable to bind address\n", argv[0]);
close(ls);
exit(1);
}
クライアント/サーバーサンプルプログラム
サービスアドレスの検索に
getaddrinfo()
を使用するIPv6 TCP
サーバー第
15
章 70fprintf(stderr, "%s: unable to listen on socket\n", argv[0]);
close(ls);
exit(1);
}
A IPv4 から IPv6 への移行のクイック リファ レンス ガイド
本ガイドは、
IPv6
サポートのために、ソースコードのシンボルや関数にどのような変更が必要 かを知りたいソケットアプリケーションプログラマ向けのものです。IPv4からIPv6への移行のクイックリファレンスガイド 既存の
IPv4
間アプリケーションは変更する必要がありますか?
付録
A
72既存の IPv4 間アプリケーションは変更する必要がありますか ?
いいえ。現在の
IPv4
アプリケーションは変更する必要はありません。新しい
IPv6
機能を利用し たい場合にだけ、アプリケーションを修正してください。IPv4からIPv6への移行のクイックリファレンスガイド 要約
:
ソースコードシンボルと関数の変更点要約 : ソースコードシンボルと関数の変更点
以下の表では、ソケットアプリケーションのプログラマが
IPv6
をサポートするためにコードを 移植する際に注意する必要がある、ソースコードシンボルと関数の変更点について示します。シンボル、データ構造体、関数呼び出しに必要な変更
表
A-1
シンボル、データ構造体、関数呼び出しに必要な変更変更が必要なソースコード 新しいソースコード
シンボル AF_INET PF_INET
AF_INET6 PF_INET6 データ構造体
sockaddr_in
u_short sin_family in_port_t sin_port sin_addr struct in_addr
sockaddr_in6
short sin6_family;
u_short sin6_port;
uint32_t sin6_flowinfo;
struct in6_addr sin6_addr;
uint32_t sin6_scope_id ifreq
ifconf
struct if_laddrreq struct if_laddrconf 関数呼び出し
gethostbyname() getaddrinfo()またはgetipnodebyname()、
freeaddrinfo()
gethostbyaddr() getipnodebyaddr()、getnameinfo()、
freeaddrinfo()
IPv4からIPv6への移行のクイックリファレンスガイド 要約
:
ソースコードシンボルと関数の変更点付録
A
74ハードコードされたデータ構造体のサイズ
移植前のアプリケーションで、sizeof(struct sockaddr_in) = sizeof(struct sockaddr)
= 16であることを確認してください。
IPv6
アドレスのデータ構造体sockaddr_in6は、従来の sockaddr_inデータ構造体より大きくなっています。マルチキャストおよび IPv4 のオプション
ループバック アドレス
ワイルドカード アドレス
表
A-2
マルチキャストおよびIPv4
のオプションIPv4 IPv6 コメント
IN_CLASSA IN_CLASSB IN_CLASSC IN_CLASSD
なし。
IPv6
のアドレス指定は クラスレスです。表
A-3
ループバック アドレスIPv4 IPv6 コメント
INADDR_LOOPBACK in6addr_loopback in6adr_loopbackは in6_addr構造体です。
表
A-4
ワイルドカード アドレスIPv4 IPv6 コメント
INADDR_ANY in6addr_any in6addr_anyはin6_addr
構造体です。
IPv4からIPv6への移行のクイックリファレンスガイド 要約
:
ソースコードシンボルと関数の変更点マルチキャストのデフォルト
IPv6 マルチキャストのオプション
注記 getsockopt()およびsetsockopt()のlevelパラメータを設定するときは、こ こに示すIPV6_*オプションすべてにIPPROTO_IPV6レベルを使用します。
表
A-5
マルチキャストのデフォルトIPv4 IPv6 コメント
IP_DEFAULT_MULTICAST_LOOP IP_DEFAULT_MULTICAST_TTL
IPV6_DEFAULT_MULTICAST_LOOP IPV6_DEFAULT_MULTICAST_HOPS
表
A-6 IPv6
マルチキャストのオプションIPv4 IPv6 コメント
IP_MULTICAST_IF IP_MULTCAST_TTL IP_MULTICAST_LOOP IP_ADD_MEMBERSHIP IP_DROP_MEMBERSHIP
IPV6_MULTICAST_IF IPV6_MULTCAST_HOPS IPV6_MULTICAST_LOOP IPV6_JOIN_GROUP IPV6_LEAVE_GROUP
IPv4からIPv6への移行のクイックリファレンスガイド 要約
:
ソースコードシンボルと関数の変更点付録
A
76IP パケットのオプション
注記 IPV6_PKTOPTIONSを使って、上記の
7
つのオプションを1
つのsetsockopt() 呼び出しにバンドルします。サービス タイプのオプション
表
A-7 IP
パケットのオプションIP_OPTIONS IPV6_PKTOPTIONS コメント
IP_RECVDSTADDR IP_RECVIF
IPV6_DESTOPTS IPV6_HOPLIMIT IPV6_HOPOPTS IPV6_NEXTHOP IPV6_PKTINFO IPV6_PKTINFO IPV6_PKTINFO
終点オプションを受信します
パケットを受信するためのユニキャスト 中継限界数です
中継点オプションを受信します 次のホップアドレスを設定します パケット情報を設定します あて先
IP
アドレスを返します受信したインタフェースインデックスを 返します
IPV6_RTHDR 経路制御ヘッダーを送受信します
IP_TTL ip_mreq
IPv6_UNICAST_HOPS ipv6_IP_OPTIONSmreq
デフォルトのユニキャスト中継限界数を 設定します
表
A-8
サービスタイプのオプションIP_TOS
IETF IPng
ワーキンググループで議論中ですIPv4からIPv6への移行のクイックリファレンスガイド 要約
:
ソースコードシンボルと関数の変更点マルチキャスト グループ、IP アドレス、IPv6 インタフェース インデックス
表A-9
マルチキャスト グループ、IPアドレス、IPv6インタフェース インデックスIPv4 IPv6 コメント
struct in_addr imr_multicast struct in6_addr ipv6mr_multiaddr
グループのマルチキャストアド レス
struct in_addr imr_interface uint32
ipv6mr_interface