Linux socket プログラミング/インターネットサービス名照会プログラム

目次

概要

初っ端から Socket 通信ではないですが、ポート番号から サービス名を検索するプログラムです。 次のポート検索プログラムを作るためにテストとして作ったものでした。ローカルの /etc/services ファイルに記述されていない ポート番号は当然変換できません。 それどころかエラーになってしまいます。

プログラムのイメージ

このプログラムで使われる関数のイメージを以下に示します。あんまり意味ないですね。

プログラム引数入力関数参照ローカルファイル
ポート番号---->getservbyport()---->/etc/services

プログラム

    1  /*
    2   * Probe service name by port number
    3   * cc getserv.c -lnsl -o getserv
    4   */
    5  #include <stdio.h>
    6  #include <errno.h>
    7  #include <netdb.h>
    8  #include <stdlib.h>
    9
   10  int
   11  main(int argc, char *argv[])
   12  {
   13      struct servent *serv ;
   14      int portnum;
   15
   16      if(argc != 2){
   17          printf("Usage: %s port\n", argv[0]);
   18          exit(1);
   19      }
   20
   21      portnum = atoi(argv[1]);
   22      if ( ( serv = getservbyport(htons(portnum),"tcp")) == NULL ){
   23          perror("getservbyport:");
   24          exit(1);
   25      }
   26      printf( "port %d is %s\n", portnum , serv->s_name );
   27      exit(0);
   28  }

ソースファイル getserv.c

実行例

プログラム名の後に引数としてポート番号を入力します。ここではポート 25 番を指定。

% ./getserv 25
port 25 is smtp

PORT 25 が SMTP である事が分かります。

解説

getservbyport()
概要ポート番号からサービス名を得る
インクルードファイル#include <netdb.h>
形式struct servent *getservbyport(int port, const char *proto);
引数int port ポート番号
const char *proto プロトコル名
戻り値成功時: servent 構造体に求めるサービス名をセットし、 その構造体のポインタを返す。
エラー: NULL ポインター

プログラム上では以下のように記述しています。

   21      portnum = atoi(argv[1]);
   22      if ( ( serv = getservbyport(htons(portnum),"tcp")) == NULL ){
   23          perror("getservbyport:");
   24          exit(1);
   25      }

21 行目ではプログラムの引数である argv[1] を char 型から int 型に変換してます。
22 行目で getservbyport() の成功時の戻り値は servent 構造体 へのポインタを返します。ここでもし serv が NULL だった場合には エラーが表示されるようになっています。以下に servent 構造体を示します。servent 構造体は の中で定義されています。

struct servent
{
  char *s_name;        /* サービス名  */
  char **s_aliases;    /* Alias(別名)リスト */
  int s_port;          /* ポート番号  */
  char *s_proto;       /* 利用するプロトコル  */
};

getservbyport() の 引数として htons(portnum) と指定していますが、これは 整数(short)「portnum」をホスト形式からネットワーク 形式のバイト順序への変換を行うためです。ということで以上です。

   26      printf( "port %d is %s\n", portnum , serv->s_name );
   27      exit(0);

最後は servent 構造体である serv の メンバー s_name (サービス名)をプリントしているだけです。知っている人にとってはだからどうした?と言われそうな事ばかりですが、私にはここまでくるだけでも大変でした。(笑)


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2022-01-03 (月) 20:17:14