2015/07/24

自分のマシンのIPアドレスを取得する

DHCPに設定したPCで、どうしてもバッチファイル内でIPアドレスを使いたいことがあった。
NIC名を指定して実行するとIPv4アドレスを返すだけのexeを作った。
Windows API 及び C/C++ を使って単機能のexeが気軽に作れるようになったのはほんとに便利だ。コード生成の設定で「/MT」を指定するとサイズは大きくなるが.Net依存無しでどのwindowsでも動くexeとなる。
コードは「C/C++あれこれ/自マシンのIPアドレスを取得」 を参考に、というかコピペで出来た。コピーアンドペースターの本領発揮。
全く同一のコードを載せちゃうのも気が引けるが後でまた必要になったときの自分用にべたっと貼っておく。
まずプロジェクトの「追加の依存ファイル」に"Ws2_32.lib"と"iphlpapi.lib"を追記します。
#include "stdafx.h"
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <errno.h>

const char* GetMyIpAddr(const char* device_name);
int GetIndexOfIF(const char* device_name);

const char* GetMyIpAddr(const char* device_name)
{
   char* ipAddr = NULL;

   //IFテーブル用のメモリを獲得します。
   DWORD dSize = 0;
   GetIfTable(NULL , &dSize, FALSE);
   PMIB_IPADDRTABLE pIpAddrTable = (PMIB_IPADDRTABLE)new char[dSize];
   DWORD ret_Get_IP_Table = GetIpAddrTable(
                    (PMIB_IPADDRTABLE)pIpAddrTable, &dSize, FALSE);

   if (ret_Get_IP_Table == NO_ERROR) {
      //指定されたデバイス名のインデックスを取得します。
      int index = GetIndexOfIF(device_name);
      for (int i = 0, l = (int)pIpAddrTable->dwNumEntries ; i < l ; i++) {
         if (index == pIpAddrTable->table[i].dwIndex) {
            in_addr ina;
            ina.S_un.S_addr = pIpAddrTable->table[i].dwAddr;
            ipAddr = inet_ntoa(ina);
            break;
         }
      }
   }
   delete [] pIpAddrTable;
   return ipAddr;
}

int GetIndexOfIF(const char* device_name)
{
   DWORD dSize = 0;
   int index = 0;

   //IFテーブル用のメモリを獲得します。
   GetIfTable(NULL , &dSize, FALSE);
   PMIB_IFTABLE pIfTable = (PMIB_IFTABLE)new char[dSize];

   DWORD ret_Get_If_Table = GetIfTable((PMIB_IFTABLE)pIfTable, &dSize, FALSE);

   if (ret_Get_If_Table == NO_ERROR) {
      for (int i = 0, l = (int)pIfTable->dwNumEntries; i < l; i++) {
         if (strcmp((const char*)pIfTable->table[i].bDescr, device_name) == 0) {
            index = pIfTable->table[i].dwIndex;;
            break;
         }
      }
   }
   delete [] pIfTable;
   return index;
}

int main(int argc, char* argv[])
{
   if (argv[1] == NULL) {
      printf("  > GetMyIp \"Network interface card name\" ");
      return 1;
   }
   const char* r = GetMyIpAddr(argv[1]);
   if (r != NULL) {
      printf(r);
   } else {
      printf("failed to get ip addr.");
      return 2;
   }
   return 0;
}

0 件のコメント:

コメントを投稿