IPv4에서 호스트가 통신을 시작하려면 서로 다른 프로토콜 여럿이 필요했다. MAC 주소를 찾는 ARP, 게이트웨이를 알려주는 ICMP 라우터 발견, 주소를 받는 DHCP, 경로를 고쳐주는 ICMP 리다이렉트가 각각 독립적으로 돌았다. IPv6는 이 네 가지 일을 ICMPv6 위에서 다섯 종류의 메시지로 통합했고, 그 통합 메커니즘이 NDP(Neighbor Discovery Protocol)다.
다섯 메시지가 각각 어떤 모양이고 호스트가 네트워크에 붙을 때 어떤 순서로 오가는지를 따라가면 NDP의 동작이 드러난다.
다섯 가지 ICMPv6 메시지

NDP는 ICMPv6 Type 133~137, 다섯 가지 메시지로 모든 일을 처리한다. IPv4에서 따로 놀던 기능이 어떤 메시지로 흡수됐는지는 다음과 같다.
| IPv4 | IPv6 NDP 메시지 | Type |
|---|---|---|
| ARP Request | Neighbor Solicitation (NS) | 135 |
| ARP Reply | Neighbor Advertisement (NA) | 136 |
| ICMP Router Discovery (요청) | Router Solicitation (RS) | 133 |
| ICMP Router Discovery (응답) | Router Advertisement (RA) | 134 |
| ICMP Redirect | Redirect | 137 |
모든 NDP 메시지는 Hop Limit이 255다. 라우터를 거치면 값이 줄어들므로, 수신 측은 255가 아닌 NDP 메시지를 외부에서 위조해 끼워 넣은 것으로 보고 버린다. NDP의 기본적인 위조 방지 장치다.
Router Solicitation (RS) — Type 133
호스트가 “여기 라우터 있나요?“라고 묻는 메시지다. 네트워크에 연결되자마자 보내 빠른 구성을 가능하게 한다.
ICMPv6 Header (8 bytes):
Type: 133, Code: 0, Checksum
Reserved: 0 (4 bytes)
Options:
Source Link-Layer Address (선택, 8 bytes)
전송: 송신 = Link-Local 또는 ::(주소 미할당 시)
목적지 = FF02::2 (All-Routers 멀티캐스트)
Router Advertisement (RA) — Type 134
라우터가 네트워크 구성 정보를 뿌리는 메시지다. RS에 응답하거나 주기적으로 멀티캐스트한다. NDP에서 가장 정보가 많은 메시지이며, 호스트의 주소 구성 방식을 좌우한다.
ICMPv6 Header (16 bytes):
Type: 134, Code: 0, Checksum
Cur Hop Limit: 64
M Flag: DHCPv6에서 주소를 받을지
O Flag: DHCPv6에서 추가 정보를 받을지
Router Lifetime: 1800 (초)
Reachable Time / Retrans Timer
Options:
Source Link-Layer Address, MTU
Prefix Information (32 bytes):
Prefix: 2001:db8::/64, Prefix Length: 64
L Flag: 1 (On-Link)
A Flag: 1 (SLAAC로 주소 생성 허용)
Valid / Preferred Lifetime
여기서 M·O 플래그 조합이 주소 구성 정책을 결정한다.
- M=0, O=0: 순수 SLAAC. 호스트가 스스로 주소를 만든다. DHCPv6 불필요.
- M=0, O=1: 주소는 SLAAC, DNS 같은 부가 정보만 DHCPv6에서.
- M=1: Stateful DHCPv6. 주소를 DHCPv6 서버가 할당.
Neighbor Solicitation (NS) — Type 135
IPv4 ARP Request를 대체한다. 목적지의 MAC을 묻거나, 이웃이 아직 살아 있는지, 또는 내가 쓰려는 주소가 중복인지 확인한다.
ICMPv6 Header (24 bytes):
Type: 135, Code: 0, Checksum
Reserved: 0 (4 bytes)
Target Address: 2001:db8::20 (찾으려는 IPv6, 16 bytes)
Options:
Source Link-Layer Address (선택, 중복 검사 시 생략)
NS의 목적지는 브로드캐스트가 아니라 Solicited-Node 멀티캐스트 주소다. FF02::1:FF00::/104 뒤에 타깃 IPv6 주소의 마지막 24비트를 붙인다. 2001:db8::1234를 찾으면 FF02::1:FF00:1234로 보낸다. 이 주소를 듣는 노드는 하위 24비트가 같은 극소수뿐이라, ARP 브로드캐스트처럼 네트워크의 모든 호스트를 깨우지 않는다. IPv6가 멀티캐스트로 불필요한 트래픽을 줄였다는 것이 이 구조를 가리킨다.
Neighbor Advertisement (NA) — Type 136
NS에 대한 응답, 또는 자신의 MAC 변경 통지다. ARP Reply에 해당한다.
ICMPv6 Header (24 bytes):
Type: 136, Code: 0, Checksum
R Flag: 라우터 여부
S Flag: NS에 대한 응답 여부 (Solicited)
O Flag: 캐시 덮어쓰기 허용 여부 (Override)
Target Address: 2001:db8::20 (자신의 IPv6, 16 bytes)
Options:
Target Link-Layer Address (8 bytes)
세 플래그가 동작을 가른다. S=1이면 NS에 대한 유니캐스트 응답, S=0이면 자발적 통지(Gratuitous NA)다. O=1이면 수신자가 기존 캐시를 새 MAC으로 덮어쓴다.
Redirect — Type 137
라우터가 호스트에게 “그 목적지는 이쪽 다음 홉이 더 빠르다"고 알려준다. 라우터만 보낼 수 있고, 보안상 Link-Local 주소에서만, Hop Limit 255로 전송된다.
ICMPv6 Header:
Type: 137, Code: 0, Checksum
Target Address: 더 나은 다음 홉 (16 bytes)
Destination Address: 최종 목적지 (16 bytes)
Options:
Target Link-Layer Address, Redirected Header (원본 패킷 일부)
호스트가 네트워크에 붙는 5단계 흐름

위 메시지들이 실제로 오가는 순서는 새 호스트가 케이블을 꽂은 직후부터 통신이 시작될 때까지로 이어진다.
1단계 — 라우터 탐색 (RS → RA)
호스트가 라우터를 찾고 네트워크 프리픽스를 받는다.
[Host → FF02::2] Router Solicitation (133)
송신: FE80::1234:5678:9abc:def0 (Link-Local)
[Router → FF02::1] Router Advertisement (134)
M=0, O=0 (SLAAC 사용)
Prefix: 2001:db8::/64, A=1, L=1
MTU: 1500, Router Lifetime: 1800
2단계 — 주소 자동 구성 (SLAAC)
RA에서 받은 프리픽스에 인터페이스 ID를 결합해 글로벌 주소를 만든다.
프리픽스 2001:db8::/64 (RA에서)
인터페이스 ID 1234:5678:9abc:def0 (Link-Local과 동일)
→ 2001:db8::1234:5678:9abc:def0 (상태: Tentative)
이 단계에서 인터페이스 ID를 만드는 방식이 갈린다. 전통적 방식인 EUI-64는 48비트 MAC을 64비트로 늘린다.
MAC 00:11:22:33:44:55
① 가운데 FFFE 삽입 → 00:11:22:FF:FE:33:44:55
② 7번째 비트 반전 → 02:11:22:FF:FE:33:44:55 (U/L 비트)
③ IPv6 형식 → 0211:22ff:fe33:4455
전체 2001:db8::211:22ff:fe33:4455
문제는 MAC이 주소에 그대로 박혀 장치를 추적할 수 있다는 점이다. 그래서 현대 OS는 RFC 4941(Privacy Extensions)이나 RFC 7217(Stable Privacy)로 무작위 또는 안정적 인터페이스 ID를 써서 MAC 노출을 막는다.
3단계 — 중복 주소 검출 (DAD)
만든 주소가 이미 쓰이고 있지 않은지 확인한다. IPv4에서는 선택이었지만 IPv6에서는 필수다.
[Host → Solicited-Node 멀티캐스트] Neighbor Solicitation (135)
송신: :: ← DAD의 결정적 특징 (아직 주소가 없음)
Target: 2001:db8::1234:5678:9abc:def0
[1초 대기]
응답 없음 → 주소 상태 Preferred, 인터페이스에 바인딩
NA 수신 → 중복, 새 인터페이스 ID로 재생성 후 재시도
송신 주소가 ::(unspecified)인 NS는 DAD다. 아직 자기 주소가 확정되지 않았기 때문이다.
4단계 — 이웃 주소 해결 (NS → NA)
실제 통신을 위해 목적지 IPv6의 MAC을 찾는다. ARP의 IPv6판이다.
[Host A 2001:db8::10 → Solicited-Node 멀티캐스트] NS (135)
Target: 2001:db8::20
Option: Source Link-Layer = aa:aa:aa:aa:aa:aa
[Host B 2001:db8::20 → Host A 유니캐스트] NA (136)
S=1 (응답), O=1 (캐시 갱신)
Option: Target Link-Layer = bb:bb:bb:bb:bb:bb
→ Host A의 Neighbor Cache: 2001:db8::20 = bb:bb:... (REACHABLE)
5단계 — 도달 가능성 추적 (NUD)
캐시한 이웃이 계속 살아 있는지 상태 머신으로 관리한다. ARP 캐시가 단순 만료에 의존하던 것과 달리, NDP는 명시적으로 상태를 전이시킨다.
REACHABLE (기본 30초) ── 시간 경과 ──▶ STALE
STALE ── 상위 계층이 전송 시도 ──▶ DELAY (5초)
DELAY ── 확인 없음 ──▶ PROBE (NS 재전송, 최대 3회)
PROBE ── NA 수신 ──▶ REACHABLE
PROBE ── 실패 ──▶ 캐시에서 제거
이 상태 머신 덕분에 죽은 이웃에 패킷을 계속 보내는 낭비를 막고, 토폴로지 변화에 빠르게 반응한다.
SLAAC와 DHCPv6
IPv6가 DHCP를 버렸다는 오해가 흔하다. 실제로는 RA의 M·O 플래그로 둘을 조합한다.
| 주소를 누가 | 서버 | RA M | RA O | |
|---|---|---|---|---|
| SLAAC | 호스트가 생성 | 불필요 | 0 | 0 |
| Stateless DHCPv6 | 호스트가 생성 | 부가 정보용만 | 0 | 1 |
| Stateful DHCPv6 | DHCPv6가 할당 | 필요 | 1 | - |
SLAAC는 서버 없이 플러그 앤 플레이로 붙지만 주소를 중앙에서 관리하기 어렵다. 대규모 환경에서 IP 대장(臺帳)을 유지해야 하면 Stateful DHCPv6를 쓴다. 둘 중 하나를 고르는 것이 아니라 RA 플래그로 정책을 선언하는 것이다.
인증이 없다
NDP는 기능을 통합했지만 기본 NDP에는 메시지 발신자를 검증하는 인증이 없다. Hop Limit 255 검사는 외부 위조만 막을 뿐 같은 링크 안의 공격자는 막지 못한다. IPv4 ARP 스푸핑과 똑같은 구조의 공격이 NDP에도 그대로 존재한다.
- RA 스푸핑: 위조 RA로 가짜 프리픽스·게이트웨이·DNS를 주입해 모든 트래픽을 공격자로 돌린다(MITM). NDP 위협 중 영향이 가장 크다.
- NS/NA 스푸핑: O=1인 위조 NA로 이웃 캐시를 오염시킨다. ARP 캐시 포이즈닝의 IPv6판이다.
- DAD DoS: 호스트가 새 주소로 DAD를 할 때마다 “이미 쓰는 중"이라고 거짓 NA를 보내, 영원히 주소를 못 받게 만든다.
- Redirect 공격: 위조 Redirect로 호스트의 다음 홉을 공격자로 바꾼다.
방어는 두 갈래다. 하나는 메시지 자체를 인증하는 것으로, SEND(SEcure Neighbor Discovery, RFC 3971)가 공개 키 기반 서명과 CGA(공개 키 해시를 인터페이스 ID로 쓰는 주소)로 위조를 차단한다. 강력하지만 PKI가 필요하고 지원 장비가 적어 보급이 제한적이다. 다른 하나는 네트워크 장비에서 비정상 메시지를 거르는 것으로, RA Guard는 호스트 포트로 들어오는 RA를 차단하고(라우터는 라우터 포트에만 있으므로), DHCPv6 Guard와 IPv6 Source Guard가 각각 비인가 DHCPv6 응답과 출발지 위조를 막는다. 실무에서는 후자가 현실적인 1차 방어선이며, 위협 모델이 높을 때 SEND를 더한다.