1. はじめに
Windows で ipconfig の実行結果みたいな情報をCで書くとどうなのだろう、と思って調べました。自分用メモ。
GetAdaptersAddresses がまぁ便利な関数ですね。
2.コード
sample.cpp
#include <stdio.h>
#include <locale.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#pragma comment(lib, "iphlpapi.lib")
void print_ip_addresses(PIP_ADAPTER_ADDRESSES pAdapter) {
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = pAdapter->FirstUnicastAddress;
while (pUnicast) {
char ipAddress[INET6_ADDRSTRLEN] = { 0 };
DWORD ipAddressLen = INET6_ADDRSTRLEN;
if (pUnicast->Address.lpSockaddr->sa_family == AF_INET) {
// IPv4アドレス
struct sockaddr_in* sa_in = (struct sockaddr_in*)pUnicast->Address.lpSockaddr;
inet_ntop(AF_INET, &(sa_in->sin_addr), ipAddress, ipAddressLen);
}
else if (pUnicast->Address.lpSockaddr->sa_family == AF_INET6) {
// IPv6アドレス
struct sockaddr_in6* sa_in6 = (struct sockaddr_in6*)pUnicast->Address.lpSockaddr;
inet_ntop(AF_INET6, &(sa_in6->sin6_addr), ipAddress, ipAddressLen);
}
printf("IP Address: %s\n", ipAddress);
pUnicast = pUnicast->Next;
}
}
int main()
{
setlocale(LC_ALL, "japanese");
DWORD dwSize = 0;
PIP_ADAPTER_ADDRESSES pAddresses = NULL, pAdapter = NULL;
// 必要なバッファサイズを取得
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, NULL, &dwSize) == ERROR_BUFFER_OVERFLOW) {
pAddresses = (PIP_ADAPTER_ADDRESSES)malloc(dwSize);
}
if (pAddresses == NULL) {
printf("メモリの確保に失敗しました。\n");
return 1;
}
// アダプター情報を取得
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &dwSize) == NO_ERROR) {
pAdapter = pAddresses;
while (pAdapter) {
printf("Adapter Name: %ls\n", pAdapter->FriendlyName);
printf("MAC Address: ");
for (DWORD i = 0; i < pAdapter->PhysicalAddressLength; i++) {
printf("%02X", pAdapter->PhysicalAddress[i]);
if (i < pAdapter->PhysicalAddressLength - 1) printf("-");
}
printf("\n");
print_ip_addresses(pAdapter); // IPアドレス出力
printf("\n");
pAdapter = pAdapter->Next;
}
}
else {
printf("アダプター情報の取得に失敗しました。\n");
}
// メモリ解放
free(pAddresses);
return 0;
}