본문 바로가기
프로그래밍

👨‍💻 [MFC] MFC 에서 IP_ADAPTER_ADDRESSES 에서 netmask 주소를 얻으려면 어떻게 해야 하나요?

by 밝음의기둥 2024. 10. 21.
반응형

👨‍💻 안녕하세요, 윌리 프로젝트의 윌리 입니다.

MFC 에서 현재 PC의 네트워크 정보를 알아야 하는 상황이 생겨서, 네트워크 정보를 얻어오는 방법 중 IP_ADAPTER_ADDRESSES 에서 netmask 주소를 얻는 방법에 대해서 알아보았습니다..


질문 >

MFC 에서 IP_ADAPTER_ADDRESSES 에서 netmask 주소를 얻으려면 어떻게 해야 하나요?

답변 >

IP_ADAPTER_ADDRESSES 구조체에서 넷마스크(서브넷 마스크) 주소를 얻으려면 FirstPrefix 멤버를 사용해야 합니다. FirstPrefix는 IP_ADAPTER_PREFIX 구조체의 링크드 리스트를 가리키며, 각 프리픽스는 주소 접두사 길이를 포함합니다. 이 정보를 사용하여 넷마스크를 계산할 수 있습니다.

다음은 MFC 애플리케이션에서 GetAdaptersAddresses를 사용하여 네트워크 어댑터 정보를 가져오고, IP 주소와 서브넷 마스크를 출력하는 예제입니다.

  1. 필요한 헤더 파일 포함:
#include <afxwin.h>
#include <iphlpapi.h>
#include <vector>
#include <ws2tcpip.h>
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")

  1. 네트워크 어댑터 정보를 가져오는 함수 작성:
std::vector<PIP_ADAPTER_ADDRESSES> GetNetworkAdapters() {
    std::vector<PIP_ADAPTER_ADDRESSES> adapters;
    ULONG outBufLen = 0;
    ULONG flags = GAA_FLAG_INCLUDE_PREFIX;
    ULONG family = AF_UNSPEC; // For both IPv4 and IPv6 addresses

    GetAdaptersAddresses(family, flags, NULL, NULL, &outBufLen);
    PIP_ADAPTER_ADDRESSES pAdapterAddresses = (PIP_ADAPTER_ADDRESSES)malloc(outBufLen);

    if (pAdapterAddresses == nullptr) {
        AfxMessageBox(_T("Error allocating memory needed to call GetAdaptersAddresses"));
        return adapters;
    }

    if (GetAdaptersAddresses(family, flags, NULL, pAdapterAddresses, &outBufLen) == NO_ERROR) {
        PIP_ADAPTER_ADDRESSES pAdapter = pAdapterAddresses;
        while (pAdapter) {
            adapters.push_back(pAdapter);
            pAdapter = pAdapter->Next;
        }
    } else {
        AfxMessageBox(_T("GetAdaptersAddresses failed"));
    }

    return adapters;
}

  1. IP 주소와 서브넷 마스크를 출력하는 함수 작성:
void PrintNetworkAdapters() {
    auto adapters = GetNetworkAdapters();

    for (const auto& adapter : adapters) {
        CString msg;
        msg.Format(_T("Adapter Name: %s\\nDescription: %s\\n"),
                   adapter->AdapterName,
                   adapter->Description);

        // IP 주소 출력
        PIP_ADAPTER_UNICAST_ADDRESS pUnicast = adapter->FirstUnicastAddress;
        while (pUnicast != nullptr) {
            SOCKADDR *sa = pUnicast->Address.lpSockaddr;
            char ipBuf[INET6_ADDRSTRLEN] = { 0 };
            char maskBuf[INET6_ADDRSTRLEN] = { 0 };

            if (sa->sa_family == AF_INET) {
                sockaddr_in *sa_in = (sockaddr_in *)sa;
                inet_ntop(AF_INET, &(sa_in->sin_addr), ipBuf, INET6_ADDRSTRLEN);
                ULONG prefixLength = pUnicast->OnLinkPrefixLength;
                ULONG mask = (0xFFFFFFFF << (32 - prefixLength)) & 0xFFFFFFFF;
                sockaddr_in maskAddr;
                maskAddr.sin_addr.s_addr = htonl(mask);
                inet_ntop(AF_INET, &(maskAddr.sin_addr), maskBuf, INET6_ADDRSTRLEN);
            } else if (sa->sa_family == AF_INET6) {
                sockaddr_in6 *sa_in6 = (sockaddr_in6 *)sa;
                inet_ntop(AF_INET6, &(sa_in6->sin6_addr), ipBuf, INET6_ADDRSTRLEN);
                ULONG prefixLength = pUnicast->OnLinkPrefixLength;
                for (int i = 0; i < 16; ++i) {
                    if (prefixLength >= 8) {
                        maskBuf[i] = 0xFF;
                        prefixLength -= 8;
                    } else {
                        maskBuf[i] = (0xFF << (8 - prefixLength)) & 0xFF;
                        prefixLength = 0;
                    }
                }
            }

            msg.AppendFormat(_T("IP Address: %s\\nSubnet Mask: %s\\n"), CString(ipBuf), CString(maskBuf));
            pUnicast = pUnicast->Next;
        }

        AfxMessageBox(msg);
    }

    // 메모리 해제
    for (auto& adapter : adapters) {
        free(adapter);
    }
}

  1. 응용 프로그램에서 함수 호출: MFC 애플리케이션의 적절한 위치 (예: 버튼 클릭 이벤트 핸들러)에서 PrintNetworkAdapters 함수를 호출합니다.
void CMyAppDlg::OnBnClickedButtonGetNetworkInfo() {
    PrintNetworkAdapters();
}

이 코드는 MFC 애플리케이션에서 GetAdaptersAddresses 함수를 사용하여 네트워크 어댑터 정보를 가져오고, 각 어댑터의 IP 주소와 서브넷 마스크를 계산하여 출력하는 예제입니다. IPv4 주소의 경우 넷마스크를 직접 계산하여 출력하고, IPv6 주소의 경우 접두사 길이를 기반으로 넷마스크를 계산합니다.


🎬 유튜브 채널 🎬

 

위로그@WiLog

📢 안녕하세요, 위로그@WiLog 시청자 여러분, 저는 윌리 입니다. 📢 위로그@WiLog 는 자기주도학습을 목적으로 라이브 스트리밍을 합니다. 📢 1인 게임 개발을 목표로 Unreal과 Blender를 학습 중입니

www.youtube.com

 

🎬 치지직 채널 🎬

 

위로그 채널 - CHZZK

지금, 스트리밍이 시작됩니다. 치지직-

chzzk.naver.com

 


반응형