#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>

// 소켓 함수 오류 출력 후 종료
void err_quit(char *msg)
{
 LPVOID lpMsgBuf;
 FormatMessage(
  FORMAT_MESSAGE_ALLOCATE_BUFFER|
  FORMAT_MESSAGE_FROM_SYSTEM,
  NULL, WSAGetLastError(),
  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  (LPTSTR)&lpMsgBuf, 0, NULL);
 MessageBox(NULL, (LPCTSTR)lpMsgBuf, (LPCTSTR)msg, MB_ICONERROR);
 LocalFree(lpMsgBuf);
 exit(-1);
}

// 소켓 함수 오류 출력
void err_display(char *msg)
{
 LPVOID lpMsgBuf;
 FormatMessage(
  FORMAT_MESSAGE_ALLOCATE_BUFFER|
  FORMAT_MESSAGE_FROM_SYSTEM,
  NULL, WSAGetLastError(),
  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  (LPTSTR)&lpMsgBuf, 0, NULL);
 printf("[%s] %s", msg, (LPCTSTR)lpMsgBuf);
 LocalFree(lpMsgBuf);
}

// 도메인 이름 -> IP 주소
BOOL GetIPAddr(char *name, IN_ADDR *addr)
{
 HOSTENT *ptr = gethostbyname(name);
 if(ptr == NULL){
  err_display("gethostbyname()");
  return FALSE;
 }
 memcpy(addr, ptr->h_addr, ptr->h_length);
 return TRUE;
}

int main(int argc, char* argv[])
{
 int retval;

 // 명령행 인자 처리
 if(argc < 4)
 {
  fprintf(stderr, "<프로그램명> <스켄할IP> <최저Port> <최대Port>식으로 명령하시오\n");
  return -1;
 }

 // 윈속 초기화
 WSADATA wsa;
 if(WSAStartup(MAKEWORD(2,2), &wsa) != 0)
  return -1;

 // 소켓 주소 구조체 초기화; 단 포트 번호는 초기화하지 않음 (밑에서 for문 돌리니까)
 SOCKADDR_IN serveraddr;
 ZeroMemory(&serveraddr, sizeof(serveraddr));
 serveraddr.sin_family = AF_INET;
 if(!GetIPAddr(argv[1], &serveraddr.sin_addr))
  return -1;

 SOCKET sock;
 int port_min = atoi(argv[2]); // 포트 번호 최소값
 int port_max = atoi(argv[3]); // 포트 번호 최대값

 for(int search_port=port_min; search_port<=port_max; search_port++)
 {
  // 소켓 생성
  sock = socket(AF_INET, SOCK_STREAM, 0);
  if(sock == INVALID_SOCKET) err_quit("socket()");

  // 접속할 포트 지정
  serveraddr.sin_port = htons((u_short)search_port);

  // connect()
  retval = connect(sock, (SOCKADDR *)&serveraddr, sizeof(serveraddr));
  if(retval == SOCKET_ERROR)
  {
   printf("[%d번]연결실패\t", search_port); // 연결이 실패하면 점을 출력
  }
  else{
   printf("\n[%d번]포트 사용가능\n", search_port); // 연결이 성공하면 포트 번호를 출력
   closesocket(sock);
  }
 }

 // 윈속 종료
 WSACleanup();
 return 0;
}


// 뭐.. 주석은 충분히 달았으니...

+ Recent posts