[cpp] ARP 테이블 열거하기

@codemaru · June 17, 2015 · 3 min read

프로그램 내에서 ARP 테이블을 뒤져야 할 때가 있다. ARP란 주소 해석 프로토콜로 IP의 실제 MAC 어드레스를 구하기 위해서 사용되는 프로토콜이다. 반대로 RARP라는 것도 있다. ARP는 네트워크의 아주 하부에 존재하는 레이어로 굉장히 중요한 역할을 한다. 실제로 네트워크 레이어를 구축할때에도 아마도 제일 먼저 만들어야 하는 부분이다.

매번 ARP를 요청하는 것은 시스템으로 봐서는 굉장히 멍청한 짓이다. 왜냐하면 IP에 해당하는 MAC 어드레스가 매번 바뀌지는 않기 때문이다. 그래서 시스템은 ARP 요청 정보를 일정 시간동안 캐시에 저장해 놓고 캐시에 저장된 요청이 오면 캐시에 있는 정보를 그대로 보내준다. ARP 캐시를 부려면 커맨드 창에서 arp -a를 입력하면 된다. 이 목록을 구하는 함수를 만들어 보도록 하자~

아래는 ARP 테이블을 열거하는 함수를 보여준다. 첫번째 인자로 열거 콜백 함수를 두번째 인자로 콜백함수에 포함될 사용자 정의 파라미터를 넣어주면 된다. 그러면 함수는 ARP 테이블의 한 행마다 fCallback함수를 호출해 준다.

ARP 테이블 열거 함수 소스 코드 다운로드

typedef BOOL (CALLBACK *CBENUMARPTBL)(MIB_IPNETROW *, PVOID );

NPDUTILAPI
BOOL WINAPI EnumArpTbl(CBENUMARPTBL fCallBack, PVOID pUserData)
{
    DWORD       cbBuffer = 0;
    char        *pBuffer = NULL;
    DWORD       result = 0;
    MIB_IPNETTABLE  *pTable;
    DWORD       i;
    MIB_IPNETROW    *row;

    while((result = GetIpNetTable((MIB_IPNETTABLE *) pBuffer, &cbBuffer, TRUE))
              == ERROR_INSUFFICIENT_BUFFER)
    {
        delete [] pBuffer;
        pBuffer = new char[cbBuffer];
        result  = GetIpNetTable((MIB_IPNETTABLE *)pBuffer, &cbBuffer, TRUE);
    }
    
    if(result != NO_ERROR)
        return FALSE;       
    
    pTable = (MIB_IPNETTABLE *)pBuffer;
    for(i = 0; i < pTable->dwNumEntries; ++i)
    {
        row = &(pTable->table[i]);
        
        if(fCallBack(row, pUserData) == FALSE)
            break;
    }
    
    delete [] pBuffer;
    return TRUE;
}

CBENUMARPTBL 함수의 첫번째 인자로 넘어오는 MIB_IPNETROW는 다음과 같이 정의된 구조체다.

typedef struct _MIB_IPNETROW {
  // 어댑터의 인덱스 번호 
  DWORD dwIndex; 

  // 물리 주소의 길이. 통상적으로 6이 된다. 왜냐하면 mac 주소는 6바이트이기 때문이다. 
  DWORD dwPhysAddrLen;

  // 물리 주소. 보통은 mac 주소가 된다. 
  BYTE bPhysAddr[MAXLEN_PHYSADDR];

  // ip 주소 
  DWORD dwAddr;

  // 다음과 같은 값을 가질 수 있다. (4 Static,3 Dynamic,2 Invalid,1 Other) 
  DWORD dwType; 
} MIB_IPNETROW, *PMIB_IPNETROW;
@codemaru
돌아보니 좋은 날도 있었고, 나쁜 날도 있었다. 그런 나의 모든 소소한 일상과 배움을 기록한다. 여기에 기록된 모든 내용은 한 개인의 관점이고 의견이다. 내가 속한 조직과는 1도 상관이 없다.
(C) 2001 YoungJin Shin, 0일째 운영 중