基本的な名前-アドレス変換

ホスト名とIPアドレスの変換

  • gethostbyname

  • gethostbyaddr

  • サービス名とポート番号の変換

  • getservbyname

  • getservbyport



  • Domain Name System(DNS)

    主にホスト名とIPアドレスマッピングを行うために使用される。ホスト名は、単純名か完全修飾ドメイン名。


    リソースレコード

    DNSの中のエントリにはリソースレコード(resource record: RR)と呼ばれる。

  • A

  • Aレコードはホスト名を32ビットのIPv4アドレスにマップする。


  • AAAA

  • AAAAレコード(クワッドAレコード)は、ホスト名を128ビットのIPv6アドレスにマップする。

  • PTRレコード

  • PTRレコード(ポインタレコード)は、IPアドレスをホスト名にマップするIPv4アドレスでは、32ビットを構成する4バイトを逆転し、各バイトを10進ASCII表現にしたものにin-addr.arpaを付け加える。結果の文字列がPTR検索(PTR query)に用いられる。


  • MXレコード

  • MXレコード(Mail eXchanger)は、特定のホストに対してメールを配送するホストを指定する。

  • CNAME

  • CNAMEは、"canonical name"(規準名)を意味し、ftpやwwwのような一般的なサービスにCNAMEレコードを割り当てるために用いる。実際のホスト名の代わりにこのようなサービス名を用いるようになれば、あるホストから別のホストへサービスを透過的に移動させることが可能になる。


  • gethostbyname

  • #include <netdb.h>
    
    struct *hostent *gethostbyname(const char *hostname);
    
    戻り値:成功なら非ヌルポインタ、失敗ならヌルポインタでh_errnoにエラーコードが設定される。


    hostent構造体
    
    struct hostent {
      char *h_name; //ホストの公式(規準)名
      char **h_aliases;//エイリアス名へのポインタ配列へのポインタ
      int h_addrtype;//ホストアドレスのタイプ: AF_INET or AFINET6
      int h_length;//アドレスの大きさ: 4 or 16
      char **h_addr_list;//IPv4またはIPv6アドレスへのポインタ配列へのポインタ
    };
    
    #define h_addr h_addr_list[0] //リスト中の最初のアドレス

    h_addr後方互換性のために設けられた。新しいコードでは、h_addrを使用すべきではない。

    gethostbynameは、エラー発生時にerrnoを設定しない。
    代わりに大域整数変数 h_errnoを、で定義されている以下の値のどれかに設定する。

  • HOST_NOT_FOUND

  • TRY_AGAIN

  • NO_RECOVERY

  • NO_DATA(NO_ADDRESSと同一)
  • NO_DATAエラーは、指定された名前が有効であるが、AレコードもAAAAレコードも持たないことを意味する。MXレコードのみを持つようなホスト名が挙げられる。

    #include <stdio.h>
    #include <netdb.h>
    
    int
    main()
    {
      char *ptr, **pptr;
      struct hostent *hptr;
      char str[512];
    
      ptr = "hatena.ne.jp";
      if ( (hptr = gethostbyname(ptr) ) == NULL) {
        herror("gethostbyname");
        return -1;
      }
     
      printf("official hostname: %s\n", hptr->h_name);
      for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)
        printf("\talias: %s", *pptr);
     
      switch (hptr->h_addrtype) {
        case AF_INET:
          pptr = hptr->h_addr_list;
          for ( ; *pptr != NULL; pptr++) {        printf("\taddress: %s\n", inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)));      }
          break;
    
        default:
          herror("unknown address type");
          break;
      }    return 0;
    }
    コンパイル, 実行
    gcc gethostbyname.c
    ./a.out




    gethostbyaddr

    gethostbyaddr関数は、与えられたバイナリのIPアドレスに対し、そのアドレスに対応するホスト名の検索を行う。

    #include <netdb.h>
    
    struct hostent *gethostbyaddr(const char *addr, size_t len, int family);
    
    戻り値:成功なら非ヌルポインタ、エラーならヌルでh_errnoが設定される。
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <stdio.h>
    
    int
    main()
    {
      struct hostent *he;
      struct in_addr addr;
    
      addr.s_addr = inet_addr("127.0.0.1");
      he = gethostbyaddr((const char *)&addr.s_addr, sizeof(addr.s_addr), AF_INET);
    
      if (he == NULL) {      
          herror("gethostbyaddr");
          return 1;
      }
    
      printf("%s\n", he->h_name);
      printf("%d\n", he->h_addrtype);
      printf("%s\n", he->h_aliases[0]);
      return 0;
    }
    



    uname関数

    uname関数は、それが実行されるホストの名前を返す。この関数は
    ゾルバライブラリの一部ではないが、ローカルホストのIPアドレスを決定するために、gethostbynameと共に用いられることが多い。

    #include <sys/utsname.h>
    int uname(struct utsname *name);
    
    戻り値:成功なら非負の値、エラーなら-1
    
    uname関数のサンプル
    
    
    #include <sys/utsname.h>
    #include <stdio.h>
    
    int
    main()
    {
      struct utsname name;
      uname(&name);
     
      printf("sysname : %s\n", name.sysname);
      printf("nodename : %s\n", name.nodename);
      printf("release : %s\n", name.release);
      printf("version : %s\n", name.version);
      printf("machine : %s\n", name.machine);
     
      return 0;
    }
    




    gethostname関数

    gethostname関数は、それが実行されているホストの名前を返す。

    #include <unistd.h>
    
    int gethostname(char *name, size_t namelen);
    
    戻り値:成功なら0、エラーなら-1

    ホスト名の最大長は、普通 ヘッダで定義されているMAXHOSTNAMELEN。

    #include <unistd.h>
    #include <stdio.h>
    #include <sys/param.h>
    
    int
    main()
    {
      char hostname[MAXHOSTNAMELEN];
      gethostname(hostname, sizeof(hostname));
      printf("%s\n", hostname);
    
      return 0;
    }