■課題5:自分の実験環境(端末)の使用/未使用ポート(ウェルノウンポートのみでok)を確認するポートスキャンプログラムを作成せよ。さらに、任意のリモート端末の使用/未使用ポートを確認するように改良せよ(加点ポイント)。なお、スクリプトを使って内部で'netstat -l'コマンドを実行し、その結果を利用するのは不可とする(ソケットプログラムを作成すること)。
■ポートスキャンプログラム
作成したポートスキャンプログラムを以下に示す。 今回はウェルノウンポートのみで良いため、ポートスキャンは1~1023まで行った。
#include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define BUFFSIZE BUFSIZ int main(int argc, char *argv[]) { int port; // ポート番号 int socket_fd; // ソケットファイルディスクリプタ char str[BUFFSIZE]; struct sockaddr_in addr; //この構造体は、internet用ソケットのアドレス情報を表す if(argc >= 3) { printf("Usage: %s [IP addr \n", argv[0]); return 1; } // 引数がない場合、ローカルホストを指定 if(argc == 1) { strcpy(str, "127.0.0.1"); } else { strcpy(str, argv[1]); } printf("Address = \"%s\" Portscan started..\n", str); // ポート1番からポートスキャンの開始。 for(port=1; port<1024; port++) { // ソケットの作成 socket(); if((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { // 返り値は、socket_fd=(ソケットファイルディスクリプタ)という整数値。 // ここで、第1引数は...通信範囲の指定。同一マシン or 他ホストとの通信のため AF_INETを指定。 // 第2引数は...通信方式の指定。TCPなのでSOCK_STREAMを指定。 // 第3引数は...0を指定して、デフォルトのプロトコルを使用する。 perror("socket"); return 1; } // ここで、addrにアドレス情報を代入する。 addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(str); // 接続先アドレスを指定 addr.sin_port = htons(port); // 接続先ポート番号を指定 // connect(); ソケットの接続要求を行う if(connect(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { // ここで、第1引数は、ソケットファイルディスクリプタを指定 // 第2引数は、アドレス情報を代入したsockaddr_in型構造体変数を指定 // 第3引数は、addrのサイズを指定 // port番のポートが開いていない時 } else { // port番のポートが開いている時に表示 printf("Port no. %4d\n", port); } // ソケットを閉じる close(socket_fd); } printf("Portscan find them.\n"); } |
■実行結果
■ローカルホスト [nw0420:~/tcpip] j04020% ./kadai5 Adress = "127.0.0.1" Portscan started.. Port no. 80 Port no. 139 Port no. 427 Port no. 548 Port no. 631 Portscan find them. [nw0420:~/tcpip] j04020% ■リモート端末(nw031) [nw0420:~/tcpip] j04020% ./kadai5 133.13.54.201 Adress = "133.13.54.201" Portscan started.. Port no. 80 Port no. 427 Port no. 548 Portscan find them. [nw0420:~/tcpip] j04020% |
■ポートスキャンについて
TCP/IPではアプリケーションごとにポート番号が用意されている。クライアントは該当するポート番号を通じてサーバのアプリケーションと接続する。このポートを外部から順番にアクセスして、応答の有無を検査することをポートスキャンと呼ぶ。