
주소를 사람이 직접 설정하면 두 가지가 곤란합니다. 같은 주소를 두 대에 잘못 줘서 충돌이 나고, 노트북처럼 네트워크를 옮겨 다니는 기기는 옮길 때마다 다시 설정해야 합니다. 게다가 전체 기기 수만큼 주소를 영구히 예약해두면 켜지지 않은 기기 몫까지 주소를 낭비하게 됩니다.
DHCP(Dynamic Host Configuration Protocol, 동적 호스트 구성 프로토콜)는 접속하는 순간 주소를 빌려주는 방식으로 이를 해결합니다. 핵심은 lease(임대)입니다. 주소를 영구히 주는 것이 아니라 기간을 정해 빌려주고, 기간이 끝나면 회수해 다른 기기에 줍니다. 켜져 있는 기기 수만큼의 주소만 있으면 됩니다.
받는 것은 주소 하나가 아닙니다. 보통 네 가지가 함께 옵니다.
이 네 가지가 있어야 비로소 통신이 됩니다. 주소만 있고 게이트웨이를 모르면 서브넷 밖으로 나갈 수 없기 때문입니다.
과정은 네 단계이고 머리글자를 따 DORA라고 부릅니다.

| 단계 | 방향 | 출발 포트 | 목적 포트 | 내용 |
|---|---|---|---|---|
| DISCOVER | 클라이언트 → 서버 | 68 | 67 | 서버가 있는지 찾음 |
| OFFER | 서버 → 클라이언트 | 67 | 68 | 줄 수 있는 주소를 제안 |
| REQUEST | 클라이언트 → 서버 | 68 | 67 | 제안 중 하나를 선택해 요청 |
| ACK | 서버 → 클라이언트 | 67 | 68 | 임대 확정 |
DHCP는 UDP를 씁니다. 서버는 67번, 클라이언트는 68번 포트입니다. TCP를 쓸 수 없는 이유는 분명합니다. 연결을 맺으려면 주소가 필요한데 지금 그 주소를 받으러 가는 중이기 때문입니다.
DISCOVER가 broadcast인 것도 같은 이유입니다. 출발지 주소로 쓸 것이 없어 0.0.0.0을 쓰고, 서버 주소도 모르니 255.255.255.255로 뿌립니다.
두 단계로 끝나지 않고 네 단계인 것은 서버가 여러 대일 수 있기 때문입니다. 여러 OFFER가 오면 클라이언트가 하나를 골라야 하고, REQUEST는 그 선택을 모든 서버에게 알리는 역할을 합니다. 선택받지 못한 서버는 제안했던 주소를 회수합니다. 임대 기간이 절반쯤 지나면 클라이언트는 같은 주소를 연장 요청하므로, 계속 쓰는 동안 주소가 바뀌지는 않습니다.
여기서부터는 데이터그램 자체 이야기입니다.
link 계층은 한 번에 실어 나를 수 있는 양에 상한이 있습니다. 이것이 MTU(Maximum Transmission Unit, 최대 전송 단위)이고, 이더넷은 1500바이트입니다. 문제는 이 값이 링크 종류마다 다르다는 점입니다.
network 계층은 경로상의 링크들이 어떤 MTU를 갖는지 미리 알지 못합니다. 그래서 아래 계층 사정은 모르는 채로 데이터그램을 내려보냅니다. 그러다 자기 MTU보다 큰 데이터그램을 내보내야 하는 라우터를 만나면 선택지는 둘뿐입니다. 버리거나, 쪼개거나.
IPv4는 쪼개는 쪽을 택했습니다.
4000바이트짜리 데이터그램이 MTU 1500인 링크를 만난 경우를 계산해보겠습니다. 헤더 20바이트를 빼면 원본 데이터는 3980바이트이고, 각 조각도 헤더 20바이트를 가지므로 데이터는 최대 1480바이트까지 실을 수 있습니다.
| 조각 | 전체 크기 | 데이터 크기 | MF | fragment offset |
|---|---|---|---|---|
| 1 | 1500 | 1480 | 1 | 0 |
| 2 | 1500 | 1480 | 1 | 185 |
| 3 | 1040 | 1020 | 0 | 370 |
주목할 점이 두 가지입니다.
첫째, offset이 185와 370인 것은 fragment offset 필드가 8바이트 단위로 세기 때문입니다. 1480번째 바이트는 1480 ÷ 8 = 185로 기록됩니다. 13비트밖에 안 되는 필드로 65535바이트 범위를 가리켜야 해서 나온 절충입니다. 그래서 마지막이 아닌 조각의 데이터 크기는 반드시 8의 배수여야 합니다.
둘째, 세 조각 모두 identification 값이 같고 MF 비트로 끝인지 아닌지를 구분합니다. 마지막 조각만 MF가 0이고 offset이 0이 아니므로, 수신 측은 "offset이 0인 조각"과 "MF가 0인 조각"을 양 끝으로 삼아 범위를 복원합니다.

조립은 최종 목적지 호스트에서만 합니다. 조각들이 서로 다른 경로를 탈 수 있어 중간 라우터가 전부를 본다는 보장이 없고, 조립에 필요한 버퍼와 타이머를 코어에 두지 않겠다는 설계 방침 때문입니다.
한 번 쪼개진 조각이 더 작은 MTU를 만나면 다시 쪼개집니다. 조각의 조각도 결국 목적지에서 한 번에 조립되므로 문제는 없습니다.