에듀테크 프로젝트 대시보드
이더넷 프레임 & MAC 주소
IP 주소보다 한 단계 아래, 실제로 랜선 위를 흐르는 건 MAC 주소가 붙은 이더넷 프레임이다. ARP가 "IP → MAC 변환"을 다룬다면, 이 글은 그 변환의 결과물인 MAC 주소 자체와 프레임 구조, 그리고 스위치가 그걸로 무슨 일을 하는지를 다룬다.
네트워크 카드(NIC)는 만들어질 때 공장에서 48비트(6바이트) 고유 번호를 하나씩 받는다. 이게 MAC(Media Access Control) 주소다. 보통 AA:BB:CC:DD:EE:FF처럼 16진수 6묶음으로 표기한다.
| 바이트 위치 | 1~3바이트 | 4~6바이트 |
|---|---|---|
| 이름 | OUI (제조사 식별자) | 장치 일련번호 |
| 예시 | AA:BB:CC | DD:EE:FF |
| 누가 정함 | IEEE 가 제조사에 할당 | 제조사가 알아서 부여 |
중요한 건 IP 주소와의 차이다.
ip link set eth0 address ... 같은 명령으로 소프트웨어적으로 바꿀 수도 있지만(MAC 스푸핑), 기본값은 공장 출고 시 고정된 값이다.
내 MAC은 Windows는 ipconfig /all, macOS/Linux는 ifconfig 또는 ip link로 확인한다.
IP 패킷이 실제로 전선 위를 흐르려면 이더넷 프레임이라는 봉투에 담겨야 한다. OSI 모델에서 말하는 "2계층(데이터링크) 캡슐화"가 바로 이거다. 아래 필드를 하나씩 눌러 어떤 역할인지 확인해 보자.
| EtherType 값 | 의미 |
|---|---|
| 0x0800 | IPv4 패킷이 들어있음 |
| 0x0806 | ARP 메시지가 들어있음 |
| 0x86DD | IPv6 패킷이 들어있음 |
스위치는 처음 켜지면 MAC 테이블이 텅 비어 있다. "어느 MAC이 어느 포트에 연결돼 있는지" 전혀 모른다는 뜻이다. 이걸 알아내는 방법은 딱 하나 — 지나가는 프레임의 출발지 MAC을 훔쳐보고 학습하는 것. 아래에서 PC 4대(A·B·C·D)가 스위치 하나에 물린 작은 네트워크를 직접 움직여 보자.
| MAC 주소 | 포트 | 상태 |
|---|---|---|
| (비어 있음) | ||
실제 스위치는 show mac address-table (Cisco) 같은 명령으로 이 표를 볼 수 있다.
일정 시간(보통 5분) 동안 안 쓰이면 항목이 지워진다(aging).
순서대로 눌러보면 이렇게 된다:
MAC 주소 중 딱 하나, FF:FF:FF:FF:FF:FF는 특별하다. "이 프레임은 이 네트워크에 있는 모든 장치에게 보내는 것"이라는 뜻이다. 스위치는 목적지 MAC이 이 값이면 무조건 (자기가 이미 알고 있어도) 모든 포트로 플러딩한다.
FF:FF:FF:FF:FF:FF를 넣고 네트워크 전체에 뿌린 뒤, 해당 IP 주인만 유니캐스트로 답한다.
스위치의 핵심 동작은 딱 dict 하나로 요약된다 — "MAC → 포트" 매핑.
class Switch: def __init__(self): self.mac_table = {} # { mac 주소: 포트 번호 } def receive_frame(self, in_port, src_mac, dst_mac, payload): # 1) 출발지 MAC을 보고 무조건 학습(또는 갱신) self.mac_table[src_mac] = in_port # 2) 목적지가 브로드캐스트거나, 아직 모르는 MAC이면 플러딩 if dst_mac == "ff:ff:ff:ff:ff:ff" or dst_mac not in self.mac_table: return self.flood(in_port, payload) # 3) 알고 있으면 해당 포트로만 정확히 전달 out_port = self.mac_table[dst_mac] return self.forward(out_port, payload) def flood(self, in_port, payload): return [p for p in self.all_ports() if p != in_port] def forward(self, out_port, payload): return [out_port]