IP 헤더를 모두 만들었다면 MAC 헤더를 붙여야 한다.
네트워크에선 엔드노드나 라우터에 존재하는 경로표를 통해 패킷을 수신할 다음 중계 노드(라우터) IP 주소를 찾았다.
그런데 왜 굳이 MAC 헤더라는 새로운 제어 정보가 필요한 것일까?
이전에 말했듯 라우터(혹은 엔드노드의 IP 담당)는 TCP/IP 규칙에 의거하여 패킷이 도착할 다음 중계 노드를 찾는다.
문제는 이더넷에서는 TCP/IP 개념이 통용되지 않기 때문에 TCP/IP 규칙에 따라 찾은 주솟값인 IP 주소를 이디넷에 전달하더라도 이더넷은 이를 파악하지 못하므로 패킷을 목적지까지 운송할 수 없다.
따라서 이더넷의 규칙에 의거하여 다음 중계지에 대한 정보를 줘야 하는데 이더넷 규칙으로 찾은 주솟값이 MAC 주소이며 바로 MAC 헤더가 이더넷의 규칙으로 다음 수신처를 찾기 위한 제어 정보인 것이다.
MAC 헤더를 만들 때도 IP 헤더와 마찬가지로 패킷의 내용물은 크게 신경쓰지 않는다.
즉, 어떤 TCP 동작 단계에 대한 패킷이든 똑같은 방식으로 이더넷에서 신호를 송/수신하는 것이다.
각 필드에 대해 조금 더 자세히 알아보자.
수신처 MAC 주소와 송신처 MAC 주소는 IP 헤더의 수신처 IP 주소와 송신처 IP 주소와 유사하다.
단지 MAC 주소는 이더넷 규칙에 의거하여 검색된 고유값이며 IP 주소는 TCP/IP 규칙에 의거하여 검색된 고유값인 것이다.
IP 주소와 MAC 주소는 몇 가지 차이점이 존재한다.
먼저 IP 주소는 32비트이지만 MAC 주소는 48비트이다.
또한 IP 주소는 그룹화의 개념이 강했다.
예를 들어 "12.34.56.78"의 경우 "12.34.56" 서브넷 내부에 있는 여러 기기 중 한 대라는 방식으로 사용되었다.
하지만 MAC 주소는 이런 개념이 없으며 48비트의 값 자체가 1개의 값이다.
DB의 AUTO_INCREMENT PK를 생각하면 편한데 어떤 Row Data의 PK가 172일 때 이 172는 특별한 의미를 가지지 않고 Row Data를 대표하기 위한 10진수 값일 뿐인 것이다.
이더 타입(EtherType) 같은 경우 IP 헤더의 프로토콜 번호와 유사하다.
IP 헤더는 IP 헤더 뒤에 있는 (TCP 헤더 + 데이터)를 패킷의 내용물로 간주하고 내용물이 어떤 TCP/IP 프로토콜에 의해 의뢰되었는지(TCP, UDP 등) 번호로 나타내었고, 이 값이 바로 프로토콜 번호였다.
이더넷을 포함한 네트워크 데이터 전송 프로토콜은 MAC 헤더 뒤에 있는 (IP 헤더 + TCP 헤더 + 데이터)를 패킷의 내용물로 간주한다.
그리고 이 패킷이 어떤 네트워크 데이터 전송 프로토콜을 사용하여 송신될 것인지 번호로 나타내는데 이 값이 이더 타입이다.
앞에서 말했듯 네트워크 데이터 전송 프로토콜은 설명하고 있는 이더넷 뿐 아니라 무선 LAN 등 많은 규칙이 존재한다.
위에선 IEEE 802.3, 0800, 0806, 86DD 같은 이더넷 계열 프로토콜의 이더 타입만 기록했지만 수많은 네트워크 데이터 전송 프로토콜 또한 각자의 이더 타입을 가지고 있다.
그렇다면 MAC 헤더에 붙이는 "MAC 주소"란 무엇일까?
이전에 말했듯 LAN 어댑터에는 "IP 주소"라는 값이 할당되어 있다.
하지만 이 IP 주소는 미리 정해져 있는 값이 아니라 어떤 서브넷에 연결되었는지에 따라 변동될 수 있는 값이다.
MAC 주소는 LAN 어댑터라는 하드웨어 기기를 제조할 때 ROM에 기록되는 고유한 값이다.
추가적인 설정을 하지 않는 이상 LAN 어댑터의 MAC 주소는 어떤 환경에서든 동일하다.
이해를 쉽게 예를 들어보자면, 클라이언트 측에 있는 LAN 어댑터에 문제가 있어 하드웨어를 교체했다고 가정하자.
이 경우 별다른 설정을 하지 않는다면 교체 전후 LAN 어댑터의 IP 주소는 동일할 것이다.
하지만 MAC 주소는 LAN 어댑터별로 다르게 할당된 고유 값이므로 MAC 주소는 달라질 것이다.
LAN 어댑터의 MAC 주소를 얻기 위하여 항상 ROM을 들러 값을 확인하지는 않는다.
나중에 자세히 배우겠지만 LAN 어댑터를 초기화 할 때 ROM에서 MAC 주소를 읽어와 메모리에 보관한다.
이후 LAN 드라이버라는 LAN 어댑터를 관리하는 SW가 설정 파일에서 설정한 대로 MAC 주소를 읽어온다.
별다른 설정을 하지 않았다면 ROM에서 읽어와 메모리에 보관한 MAC 주소를 불러오겠지만 드라이버 설정을 바꿈으로써 LAN 어댑터에 할당된 MAC 주소와 다른 값을 활용할 수도 있다.
이제 MAC 주소를 알았은이 수신처 MAC 주소와 송신처 MAC 주소에 대해 자세히 알아보자.
먼저 송신처 MAC 주소이다.
이는 송신처 IP 주소를 기록하는 것과 동일한 이유로 기록한다.
여러 개의 LAN 어댑터가 장착되어 있을 경우 어떤 LAN 어댑터를 통해 패킷을 송신할지 정해야 하므로 패킷을 송신할 LAN 어댑터에 할당된 MAC 주소를 기록하는 것이다.
문제는 수신처 MAC 주소이다.
MAC 주소는 하드웨어에 기록된 고유한 값이다. 송신처 MAC 주소는 현재 패킷이 존재하고 있는 기기에 값이 저장되어 있으므로 쉽게 그 값을 구할 수 있다.
하지만 수신처 MAC 주소는 패킷이 보내져야 할 하드웨어에 기록되어 있으므로 이 값을 파악하기는 까다롭다.
이더넷을 통해 이 패킷을 전달하기 위해선 상대의 MAC 주소를 알아야 한다.
패킷이 전달될 다음 LAN 어댑터의 IP는 현재 패킷이 존재하는 기기 내부 경로표를 통해 쉽게 구할 수 있었으나 MAC 주소는 현재 기기에 저장되어 있는 값이 아니다.
즉, 이더넷 규칙 목적지를 파악하지 못하므로 목적지를 알지만 데이터는 보낼 수는 없는 것이다.
이런 문제를 해결하기 위하여 라우터 같은 중계 노드나 엔드 노드에서는 패킷을 전달할 다음 노드의 MAC 주소를 조사하는 "ARP"라는 동작을 실행한다.
ARP 과정을 통해 수신처 MAC 주소까지 파악했다면 MAC 헤더를 완성시킬 수 있다.
프로토콜 스택의 IP 담당은 MAC 헤더를 이전에 만든 (IP 헤더 + TCP 헤더 + 데이터) 패킷에 붙임으로써 패킷을 완성시킨다.
이렇게 LAN 어댑터에 건네주기 전 MAC 헤더를 붙인 완성된 패킷을 만듦으로써 LAN 어댑터는 항상 완성된 패킷만을 받게 된다.
LAN 어댑터는 항상 완성된 패킷만을 받기 때문에 IP 뿐만이 아닌 다른 프로토콜을 활용해 통신할 때도 동일한 방식으로 동작하여 문제 없이 데이터를 보낼 수 있게 되며 여러 개의 LAN 어댑터를 활용할 필요성이 없어진다.
ARP란 Address Resolution Protocol의 약자이다.
이 개념을 알기 위해선 "Resolutoin"이라는 단어에 대해 알아보면 좋다.
이전에 DNS를 공부할 때 "Name Resolution"이라는 동작을 수행함으로써 도메인명에 해당하는 IP 주소를 찾았으며 이 Name Resolution을 실행시키는 것이 리졸버(Resolver)였다.
Resolution은 "Resolve"의 명사형으로써 "분석하여 답을 찾음"이라는 의미를 가진다.
단어를 파악한 뒤 ARP의 풀네임을 확인해 보자.
Name Resolution은 Domain Name → IP 주소로 변환하는 작업이었다.
그렇다면 Address Resolution Protocol은 Address를 무언가로 변환해 주는 작업일 것이다.
일반적으로 네트워크에선 주소(Address)라고 하면 IP 주소를 말하는 경우가 많다.
ARP란 IP 주소를 무언가로 변환해주는 작업을 말하며 이때 "무언가"가 바로 MAC 주소 되는 것이다.
즉, ARP란 IP 주소를 MAC 주소로 변환하는 작업을 의미하며, 조금 더 상세히 말하자면 수신지 IP 주소를 해당 LAN 어댑터의 MAC 주소로 변환하는 과정을 의미한다.
ARP 동작 방식은 간단하다.
이더넷에는 서브넷 내에 연결되어 있는 모든 기기에게 패킷을 전달하는 브로드캐스트라는 구조가 있다.
ARP의 경우 브로드캐스트 구조를 통해 수신지 IP 주소를 기록한 패킷을 연결된 모든 기기에게 보낸다.
브로드캐스트로 보내진 패킷을 받은 기기 중 패킷에 적혀 있는 수신지 IP 주소와 동일한 IP 주소를 가진 LAN 어댑터가 있을 텐데 이 LAN 어댑터가 자신의 MAC 주소를 패킷 송신 측에게 알려주는 것이다.
이 ARP 작업을 수행하면 패킷 송신 측에서는 수신지 IP 주소에 해당하는 기기의 MAC 주소를 알 수 있으며 MAC 헤더에 수신지 MAC 주소를 기록할 수 있게 되는 것이다.
만약 패킷을 다음 수신지로 보낼 때마다 이 동작을 수행한다고 가정해 보자.
네트워크에서는 1개 노드에 패킷이 띄엄띄엄 오는 것이 아니라 계속해서 패킷이 도착한다.
이때 패킷이 도착할 때마다 ARP 작업을 수행하면 자원이 너무 많이 소요된다.
따라서 ARP를 통해 조사한 결과는 ARP 캐시라는 메모리 영역에 보존한 뒤 다시 이용한다.
(당연하겠지만 송신지 네트워크 기기 내부에 저장된다)
패킷을 송신할 때 우선 ARP 캐시를 조사하고 만약 ARP 캐시에 수신지 MAC 주소가 존재하지 않으면 ARP 작업을 수행하는 것이다.
물론 ARP 캐시를 사용하면 ARP 과정에 소요되는 자원을 아낄 수 있지만 이 데이터를 영구적으로 활용할 수는 없다.
LAN 어댑터에 할당된 IP 주소는 변경될 수도 있는 값이며 IP 주소 값이 변경되지 않았더라도 LAN 어댑터의 문제가 발생하여 수신 측의 기기를 바꿀 수도 있기 때문이다.
이 경우 ARP 캐시에 저장된 데이터와 현실 데이터가 일치하지 않아 문제가 발생할 수 있다.
따라서 ARP 캐시에 저장된 값은 일정 시간이 되면 삭제되도록 설정되어 있다.
삭제 동작은 데이터가 유효하든 유효하지 않든 시간이 지나면 무조건 일어나는 동작으로 강제적이라고 할 수는 있지만 문제가 발생하지는 않으므로 안전한 방법이라고도 할 수 있다.
물론 정해진 시간 내에 IP 주소나 MAC 주소가 변경되었을 경우에는 제대로 통신이 불가할 것이며 이런 문제를 해결하기 위해 ARP 캐시의 내용을 수동으로 관리할 수 있게 해 놨다.