🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

A

AI Generated

2025. 12. 5. · 55 Views

이더넷과 이더넷 프레임 완벽 가이드

네트워크의 기초가 되는 이더넷 표준과 프레임 구조를 초급 개발자 눈높이에서 쉽게 설명합니다. 데이터가 네트워크를 통해 어떻게 전달되는지 그 원리를 이해할 수 있습니다.


목차

  1. 이더넷_표준_이해
  2. 통신_매체_표기_형태_해석
  3. 이더넷_프레임_구조
  4. 프리앰블_역할
  5. MAC_주소_이해
  6. 타입_길이_필드와_FCS
  7. 토큰_링_참고

1. 이더넷 표준 이해

신입 개발자 김개발 씨가 회사에서 처음으로 서버실에 들어갔습니다. 수많은 케이블이 스위치에 연결되어 있는 모습을 보며 문득 궁금해졌습니다.

"이 케이블들은 어떻게 서로 데이터를 주고받는 걸까요?"

**이더넷(Ethernet)**은 컴퓨터들이 유선 네트워크에서 서로 통신하기 위한 표준 규약입니다. 마치 도로에서 자동차들이 교통 법규를 따라야 안전하게 이동할 수 있듯이, 컴퓨터들도 이더넷이라는 규칙을 따라야 데이터를 주고받을 수 있습니다.

1980년대에 탄생한 이후 지금까지 가장 널리 사용되는 LAN 기술입니다.

다음 코드를 살펴봅시다.

# 이더넷 표준 IEEE 802.3 규격 예시
ethernet_standards = {
    "10BASE-T": {"speed": "10 Mbps", "media": "트위스티드 페어"},
    "100BASE-TX": {"speed": "100 Mbps", "media": "트위스티드 페어"},
    "1000BASE-T": {"speed": "1 Gbps", "media": "트위스티드 페어"},
    "10GBASE-T": {"speed": "10 Gbps", "media": "트위스티드 페어"},
}

# 현재 사용 중인 이더넷 표준 확인
for standard, spec in ethernet_standards.items():
    print(f"{standard}: 속도 {spec['speed']}, 매체 {spec['media']}")

김개발 씨는 입사 첫 주, 네트워크 담당 선배 박시니어 씨와 함께 서버실을 둘러보게 되었습니다. 깔끔하게 정리된 케이블들과 깜빡이는 LED를 보며 김개발 씨가 물었습니다.

"선배, 이 케이블들이 전부 이더넷 케이블인가요?" 박시니어 씨가 고개를 끄덕이며 설명을 시작했습니다. "맞아요.

우리가 사용하는 대부분의 유선 네트워크는 이더넷 표준을 따르고 있어요." 그렇다면 이더넷이란 정확히 무엇일까요? 쉽게 비유하자면, 이더넷은 마치 전 세계 공통의 교통 법규와 같습니다.

한국에서 운전면허를 따면 다른 나라에서도 비슷한 규칙으로 운전할 수 있듯이, 이더넷 표준을 따르는 장비들은 제조사가 달라도 서로 통신할 수 있습니다. 삼성 컴퓨터와 애플 맥북이 같은 네트워크에서 문제없이 데이터를 주고받을 수 있는 이유가 바로 이 때문입니다.

이더넷이 없던 시절에는 어땠을까요? 1970년대까지만 해도 각 회사마다 자체적인 네트워크 방식을 사용했습니다.

IBM 장비는 IBM끼리만, DEC 장비는 DEC끼리만 통신할 수 있었습니다. 마치 각 나라가 완전히 다른 교통 규칙을 사용해서 국경을 넘으면 운전을 못하는 상황과 같았습니다.

바로 이런 문제를 해결하기 위해 **IEEE(미국전기전자학회)**에서 802.3이라는 표준을 제정했습니다. 이더넷 표준의 핵심은 세 가지입니다.

첫째, 물리적 연결 방식을 정의합니다. 어떤 케이블을 사용할지, 커넥터 모양은 어떠해야 하는지를 규정합니다.

둘째, 데이터 전송 속도를 정의합니다. 10Mbps, 100Mbps, 1Gbps 등 다양한 속도 규격이 있습니다.

셋째, 데이터 형식을 정의합니다. 이것이 바로 우리가 뒤에서 배울 이더넷 프레임입니다.

위의 코드를 살펴보면 다양한 이더넷 표준을 확인할 수 있습니다. 10BASE-T는 10Mbps 속도를 지원하는 초기 규격이고, 현재 가정에서 많이 사용하는 것은 1000BASE-T, 즉 기가비트 이더넷입니다.

데이터센터에서는 10GBASE-T 이상의 초고속 이더넷을 사용합니다. 실제 현업에서 개발자가 이더넷 표준을 직접 다룰 일은 많지 않습니다.

하지만 네트워크 문제가 발생했을 때, 기본 개념을 알고 있으면 원인을 파악하기가 훨씬 수월합니다. 예를 들어 "왜 파일 전송이 느리지?"라는 질문에 "아, 이 구간이 100BASE-TX라서 최대 100Mbps밖에 안 나오는구나"라고 답할 수 있게 됩니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 서버실의 케이블들이 조금은 친근하게 느껴졌습니다.

"결국 이 케이블들이 공통의 언어로 대화하고 있는 거군요!"

실전 팁

💡 - 이더넷 표준 이름에서 숫자는 속도(Mbps)를, BASE는 베이스밴드 전송을, 마지막 글자는 케이블 종류를 의미합니다

  • 현재 가장 보편적인 규격은 1000BASE-T(기가비트 이더넷)입니다

2. 통신 매체 표기 형태 해석

김개발 씨가 네트워크 장비를 구매하려고 스펙을 살펴보다가 이상한 표기를 발견했습니다. "10BASE-T, 100BASE-FX...

이게 대체 무슨 암호일까요?" 마치 외계어처럼 보이는 이 표기법에는 사실 명확한 규칙이 숨어 있습니다.

이더넷 표기법은 전송 속도 + 전송 방식 + 케이블 유형의 조합으로 구성됩니다. 마치 자동차 모델명이 엔진 배기량과 옵션을 나타내듯이, 이더넷 표기법도 해당 규격의 핵심 특성을 압축해서 보여줍니다.

이 규칙만 알면 어떤 표기도 해석할 수 있습니다.

다음 코드를 살펴봅시다.

# 이더넷 표기법 해석기
def parse_ethernet_standard(standard):
    # 예: "1000BASE-T" 분석
    parts = standard.split("BASE")
    speed = parts[0]  # 속도 (Mbps)

    suffix = parts[1].replace("-", "") if len(parts) > 1 else ""

    media_types = {
        "T": "트위스티드 페어 (UTP/STP)",
        "TX": "트위스티드 페어 카테고리5",
        "FX": "광섬유 (멀티모드)",
        "LX": "광섬유 (싱글모드, 장거리)",
        "SX": "광섬유 (싱글모드, 단거리)",
    }

    media = media_types.get(suffix, "알 수 없음")
    return f"속도: {speed}Mbps, 매체: {media}"

# 표기법 해석 실행
print(parse_ethernet_standard("1000BASE-T"))
print(parse_ethernet_standard("100BASE-FX"))

김개발 씨가 회사에서 네트워크 장비 견적서를 받았습니다. 스위치 스펙에 "10/100/1000BASE-T 지원"이라고 적혀 있는데, 도무지 무슨 말인지 이해가 되지 않았습니다.

옆자리 박시니어 씨에게 물어보기로 했습니다. "선배, 이 BASE-T가 뭔가요?

마치 암호 같아요." 박시니어 씨가 웃으며 답했습니다. "암호처럼 보이지만, 규칙만 알면 누구나 읽을 수 있어요.

마치 자동차 번호판처럼요." 이더넷 표기법은 세 부분으로 나뉩니다. 첫 번째는 숫자입니다.

이것은 전송 속도를 Mbps 단위로 나타냅니다. 10은 10Mbps, 100은 100Mbps, 1000은 1Gbps를 의미합니다.

가장 직관적인 부분이죠. 두 번째는 BASE입니다.

이것은 베이스밴드(Baseband) 전송 방식을 의미합니다. 베이스밴드란 케이블 전체 대역폭을 하나의 신호 전송에 사용한다는 뜻입니다.

과거에는 BROAD(브로드밴드)도 있었지만, 현재 이더넷은 거의 모두 베이스밴드 방식을 사용합니다. 세 번째는 케이블 유형을 나타내는 알파벳입니다.

여기가 가장 헷갈리는 부분인데, 몇 가지만 기억하면 됩니다. T트위스티드 페어(Twisted Pair) 케이블을 의미합니다.

우리가 흔히 보는 랜선이 바로 이것입니다. 구리선 여덟 가닥을 두 개씩 꼬아서 만든 케이블이죠.

가정과 사무실에서 가장 많이 사용합니다. F, L, S가 붙으면 광섬유(Fiber) 케이블입니다.

FX는 멀티모드 광섬유, LX는 장거리용 싱글모드, SX는 단거리용 싱글모드를 의미합니다. 광섬유는 빛으로 데이터를 전송하기 때문에 더 빠르고 멀리 보낼 수 있지만, 가격이 비쌉니다.

위의 코드를 살펴보면 이런 표기법을 해석하는 간단한 함수를 만들었습니다. 문자열을 "BASE"를 기준으로 분리하고, 접미사를 통해 케이블 종류를 판별합니다.

실무에서 이 표기법을 알면 장비 선택이 훨씬 수월해집니다. 예를 들어 서버실과 사무실 사이에 100미터가 넘는 거리를 연결해야 한다면, 트위스티드 페어의 최대 거리가 100미터이므로 광섬유 케이블(1000BASE-LX 등)을 선택해야 합니다.

김개발 씨가 고개를 끄덕였습니다. "아, 그러니까 1000BASE-T는 기가비트 속도에 일반 랜선을 쓴다는 뜻이군요!" 박시니어 씨가 엄지를 치켜세웠습니다.

"정확해요!"

실전 팁

💡 - T(트위스티드 페어)는 최대 100미터, 광섬유는 종류에 따라 수십 킬로미터까지 가능합니다

  • 사무실 환경에서는 대부분 1000BASE-T로 충분합니다

3. 이더넷 프레임 구조

김개발 씨가 네트워크 패킷 분석 도구인 Wireshark를 처음 실행했습니다. 화면에 쏟아지는 수많은 데이터를 보며 당황했습니다.

"이 데이터들이 어떤 구조로 되어 있는 건지 전혀 모르겠어요." 선배가 말했습니다. "이더넷 프레임 구조부터 알아야 해요."

**이더넷 프레임(Ethernet Frame)**은 네트워크에서 데이터를 전송하는 기본 단위입니다. 마치 편지를 보낼 때 봉투에 보내는 사람과 받는 사람 주소를 적듯이, 이더넷 프레임도 데이터와 함께 출발지/목적지 정보를 담고 있습니다.

프레임의 각 부분은 정해진 역할을 수행합니다.

다음 코드를 살펴봅시다.

# 이더넷 프레임 구조 시뮬레이션
class EthernetFrame:
    def __init__(self, dest_mac, src_mac, data):
        self.preamble = "10101010" * 7      # 7바이트 프리앰블
        self.sfd = "10101011"               # 1바이트 SFD
        self.dest_mac = dest_mac            # 6바이트 목적지 MAC
        self.src_mac = src_mac              # 6바이트 출발지 MAC
        self.type_length = len(data)        # 2바이트 타입/길이
        self.data = data                    # 46-1500바이트 데이터
        self.fcs = self.calculate_fcs()     # 4바이트 FCS

    def calculate_fcs(self):
        # CRC-32 체크섬 계산 (간소화)
        return hash(self.data) & 0xFFFFFFFF

    def get_frame_size(self):
        return 8 + 6 + 6 + 2 + len(self.data) + 4

frame = EthernetFrame("AA:BB:CC:DD:EE:FF", "11:22:33:44:55:66", "Hello")
print(f"프레임 크기: {frame.get_frame_size()} 바이트")

김개발 씨는 네트워크 문제를 디버깅하기 위해 Wireshark를 설치했습니다. 패킷 캡처를 시작하자 화면에 수많은 데이터가 쏟아졌습니다.

하지만 무엇이 무엇인지 전혀 구분할 수가 없었습니다. 박시니어 씨가 다가와 화면을 가리켰습니다.

"이걸 이해하려면 먼저 이더넷 프레임 구조를 알아야 해요. 프레임은 네트워크 데이터의 기본 단위거든요." 이더넷 프레임이란 무엇일까요?

쉽게 비유하자면, 프레임은 마치 택배 상자와 같습니다. 택배 상자에는 받는 사람 주소, 보내는 사람 주소, 내용물, 그리고 파손 방지용 완충재가 들어있습니다.

이더넷 프레임도 마찬가지로 목적지 주소, 출발지 주소, 실제 데이터, 그리고 오류 검출 코드를 담고 있습니다. 프레임의 구조를 순서대로 살펴보겠습니다.

가장 앞에는 **프리앰블(Preamble)**과 **SFD(Start Frame Delimiter)**가 있습니다. 이것은 "지금부터 프레임이 시작됩니다"라고 알려주는 신호입니다.

총 8바이트를 차지합니다. 다음은 목적지 MAC 주소출발지 MAC 주소입니다.

각각 6바이트씩, 총 12바이트입니다. MAC 주소는 네트워크 카드의 고유한 물리적 주소로, 세상에 단 하나뿐입니다.

그 다음은 타입/길이 필드로 2바이트입니다. 이 필드는 뒤에 오는 데이터가 어떤 종류인지(IP, ARP 등) 또는 데이터의 길이가 얼마인지를 나타냅니다.

데이터(페이로드) 영역은 실제로 전송하려는 내용이 들어가는 곳입니다. 최소 46바이트에서 최대 1500바이트까지 담을 수 있습니다.

만약 보내려는 데이터가 46바이트보다 작으면 패딩을 추가해서 채웁니다. 마지막으로 **FCS(Frame Check Sequence)**가 4바이트 있습니다.

이것은 프레임이 전송 중에 손상되지 않았는지 확인하는 체크섬입니다. 위의 코드에서는 이더넷 프레임을 파이썬 클래스로 표현했습니다.

각 필드의 역할과 크기를 확인할 수 있습니다. 실제 네트워크에서는 이런 구조의 바이너리 데이터가 초당 수백만 개씩 오고 갑니다.

실무에서 이 구조를 알면 Wireshark 같은 도구로 네트워크 문제를 분석할 때 큰 도움이 됩니다. "아, 이 패킷의 목적지 MAC이 브로드캐스트네"라거나 "FCS 오류가 많이 발생하는 걸 보니 케이블에 문제가 있을 수 있겠다"라고 판단할 수 있게 됩니다.

김개발 씨가 Wireshark 화면을 다시 보았습니다. 이제 각 필드가 눈에 들어오기 시작했습니다.

"프레임 구조를 알고 보니까 전혀 다르게 보이네요!"

실전 팁

💡 - 이더넷 프레임의 최소 크기는 64바이트, 최대 크기는 1518바이트입니다

  • MTU(Maximum Transmission Unit)가 1500바이트인 이유가 바로 데이터 필드의 최대 크기 때문입니다

4. 프리앰블 역할

김개발 씨가 궁금해했습니다. "프레임 맨 앞에 있는 프리앰블이 뭔가요?

왜 데이터도 아닌 것이 8바이트나 차지하는 거죠?" 박시니어 씨가 설명했습니다. "그건 마치 달리기 경주에서 '제자리에, 준비, 땅!' 하는 것과 같아요."

**프리앰블(Preamble)**은 이더넷 프레임의 시작을 알리는 동기화 신호입니다. 7바이트의 프리앰블과 1바이트의 SFD로 구성되며, 총 8바이트입니다.

마치 라디오 방송에서 "삐" 소리로 정시를 알리듯이, 프리앰블은 수신 장치에게 "지금부터 데이터가 시작됩니다"라고 알려줍니다.

다음 코드를 살펴봅시다.

# 프리앰블과 SFD 구조 시각화
def visualize_preamble():
    # 프리앰블: 10101010 패턴이 7번 반복
    preamble_byte = "10101010"
    preamble = [preamble_byte] * 7

    # SFD: 10101011 (마지막이 11로 끝남)
    sfd = "10101011"

    print("=== 프리앰블 (7 바이트) ===")
    for i, byte in enumerate(preamble):
        print(f"바이트 {i+1}: {byte}")

    print("\n=== SFD (1 바이트) ===")
    print(f"SFD: {sfd} <- 마지막 비트가 1로 프레임 시작 표시")

    return preamble + [sfd]

sync_signal = visualize_preamble()
print(f"\n총 동기화 신호: {len(sync_signal)} 바이트")

어느 날 김개발 씨가 이더넷 프레임 구조를 공부하다가 의문이 생겼습니다. "프리앰블이라는 게 8바이트나 되는데, 이게 왜 필요한 거죠?

그냥 바로 데이터를 보내면 안 되나요?" 박시니어 씨가 비유를 들어 설명했습니다. "라디오 방송 들어본 적 있죠?

정각이 되면 '삐삐삐' 하고 시보가 울리잖아요. 그 소리를 듣고 사람들이 '아, 지금이 정각이구나'라고 알 수 있어요.

프리앰블도 비슷한 역할을 해요." 컴퓨터 네트워크에서 데이터는 전기 신호로 전송됩니다. 문제는 송신 장치와 수신 장치의 **클럭(시계)**이 완벽하게 일치하지 않는다는 것입니다.

아무리 정밀한 장치라도 미세한 오차가 있습니다. 만약 동기화 없이 바로 데이터를 보내면 어떻게 될까요?

수신 장치가 신호의 시작점을 정확히 알 수 없습니다. "이게 0인가 1인가?" "지금 첫 번째 비트인가 두 번째 비트인가?" 이런 혼란이 생깁니다.

마치 전화 통화에서 상대방이 말을 시작하는 순간을 놓쳐서 첫 단어를 못 듣는 것과 같습니다. 그래서 프리앰블이 필요합니다.

프리앰블은 10101010 패턴이 7번 반복됩니다. 이 규칙적인 패턴을 수신 장치가 받으면서 클럭을 맞춥니다.

"아, 이 간격으로 0과 1이 교대로 오는구나. 이 속도에 내 클럭을 맞추면 되겠다." 프리앰블의 마지막에는 **SFD(Start Frame Delimiter)**가 옵니다.

10101011로, 마지막 두 비트가 연속으로 1입니다. 이것을 보면 수신 장치는 "프리앰블이 끝났고, 지금부터 진짜 데이터가 시작된다"라고 인식합니다.

위의 코드를 보면 프리앰블과 SFD의 비트 패턴을 시각화했습니다. 7바이트의 10101010 패턴 뒤에 10101011이 오는 것을 확인할 수 있습니다.

흥미로운 점은, 현대의 고속 이더넷에서는 송수신 장치가 매우 정밀해져서 프리앰블의 중요성이 예전만큼 크지 않습니다. 하지만 하위 호환성과 표준 준수를 위해 여전히 사용됩니다.

김개발 씨가 고개를 끄덕였습니다. "결국 프리앰블은 '지금부터 시작합니다'라는 약속된 신호군요.

덕분에 수신 장치가 데이터를 놓치지 않고 받을 수 있는 거고요."

실전 팁

💡 - 프리앰블은 실제 데이터가 아니므로 프레임 크기 계산에서 제외하기도 합니다

  • 기가비트 이더넷에서는 Inter-Packet Gap도 중요한 역할을 합니다

5. MAC 주소 이해

김개발 씨가 새 노트북을 받았습니다. 네트워크 설정을 하다가 "MAC 주소"라는 항목을 발견했습니다.

"AA:BB:CC:11:22:33 같은 이상한 숫자인데, 이게 뭐고 왜 필요한 건가요?" IP 주소와는 어떻게 다른 걸까요?

**MAC 주소(Media Access Control Address)**는 네트워크 장치의 고유한 물리적 주소입니다. 48비트(6바이트)로 구성되며, 제조 시점에 하드웨어에 새겨집니다.

마치 사람의 지문처럼 전 세계에서 단 하나뿐인 고유한 식별자입니다. 이더넷 프레임에서는 수신지와 송신지 MAC 주소가 각각 6바이트씩 포함됩니다.

다음 코드를 살펴봅시다.

# MAC 주소 분석기
def analyze_mac_address(mac):
    # MAC 주소 형식: XX:XX:XX:XX:XX:XX
    parts = mac.split(":")

    # 앞 3바이트: OUI (제조사 식별)
    oui = ":".join(parts[:3])
    # 뒤 3바이트: 장치 고유 번호
    nic = ":".join(parts[3:])

    # 제조사 데이터베이스 (예시)
    manufacturers = {
        "00:1A:2B": "Apple Inc.",
        "00:50:56": "VMware",
        "AC:DE:48": "Samsung",
    }

    manufacturer = manufacturers.get(oui, "알 수 없는 제조사")

    print(f"MAC 주소: {mac}")
    print(f"OUI (제조사 코드): {oui} -> {manufacturer}")
    print(f"NIC (장치 번호): {nic}")

    # 유니캐스트/멀티캐스트 확인
    first_byte = int(parts[0], 16)
    is_multicast = first_byte & 0x01
    print(f"타입: {'멀티캐스트' if is_multicast else '유니캐스트'}")

analyze_mac_address("00:1A:2B:3C:4D:5E")

김개발 씨가 회사에서 새 노트북을 지급받았습니다. IT 부서에서 "MAC 주소를 알려달라"고 했는데, 처음 듣는 용어였습니다.

터미널에서 확인해보니 "AA:BB:CC:11:22:33" 같은 이상한 값이 나왔습니다. "선배, MAC 주소가 뭔가요?

IP 주소랑 다른 건가요?" 박시니어 씨가 설명을 시작했습니다. "MAC 주소는 네트워크 카드의 '주민등록번호'라고 생각하면 돼요.

태어날 때부터 정해져 있고, 바꿀 수 없는 고유한 번호죠." MAC 주소IP 주소의 차이점은 무엇일까요? IP 주소는 마치 집 주소와 같습니다.

이사를 가면 바뀌고, 같은 건물에 여러 사람이 살 수 있습니다. 반면 MAC 주소는 지문과 같습니다.

평생 바뀌지 않고, 전 세계에서 단 하나뿐입니다. MAC 주소는 48비트, 즉 6바이트로 구성됩니다.

보통 16진수로 표기하며, 콜론(:)이나 하이픈(-)으로 구분합니다. 예를 들어 "00:1A:2B:3C:4D:5E" 형태입니다.

이 6바이트는 두 부분으로 나뉩니다. 앞의 3바이트는 **OUI(Organizationally Unique Identifier)**라고 합니다.

이것은 제조사를 나타내는 코드입니다. IEEE에서 각 제조사에게 고유한 OUI를 할당합니다.

예를 들어 Apple, Samsung, Intel 등 각 회사마다 고유한 OUI가 있습니다. 뒤의 3바이트는 NIC(Network Interface Controller) 고유 번호입니다.

제조사가 자체적으로 할당하는 일련번호로, 같은 제조사 내에서 중복되지 않습니다. 위의 코드에서는 MAC 주소를 분석하는 함수를 만들었습니다.

OUI를 추출해서 제조사를 확인하고, 유니캐스트인지 멀티캐스트인지도 판별합니다. 이더넷 프레임에서 MAC 주소는 핵심적인 역할을 합니다.

스위치는 MAC 주소를 보고 프레임을 어느 포트로 보낼지 결정합니다. 목적지 MAC 주소가 "FF:FF:FF:FF:FF:FF"면 브로드캐스트로, 모든 장치에게 전송됩니다.

실무에서 MAC 주소를 활용하는 대표적인 예가 MAC 필터링입니다. 특정 MAC 주소만 네트워크에 접속하도록 허용하는 보안 기능입니다.

하지만 MAC 주소는 소프트웨어로 변조가 가능하므로, 강력한 보안 수단은 아닙니다. 김개발 씨가 자신의 노트북 MAC 주소를 확인했습니다.

"아, 제 노트북도 전 세계에서 유일한 주소를 가지고 있군요. 신기하네요!"

실전 팁

💡 - MAC 주소는 소프트웨어로 변경 가능하지만, 실제 하드웨어 주소는 변하지 않습니다

  • Wireshark에서 OUI를 기반으로 제조사를 자동으로 표시해줍니다

6. 타입 길이 필드와 FCS

김개발 씨가 패킷 분석을 하다가 이상한 점을 발견했습니다. "이 필드가 어떤 패킷에서는 0x0800이고, 어떤 패킷에서는 46이에요.

같은 위치인데 왜 값이 다른 거죠?" 타입/길이 필드의 이중적인 역할에 대해 알아봅시다.

타입/길이 필드는 이더넷 프레임에서 2바이트를 차지하며, 값에 따라 두 가지 역할을 합니다. 1536(0x0600) 이상이면 상위 프로토콜 타입을, 그 미만이면 데이터의 길이를 나타냅니다.

**FCS(Frame Check Sequence)**는 프레임 끝의 4바이트로, 전송 중 오류를 검출하는 체크섬입니다.

다음 코드를 살펴봅시다.

# 타입/길이 필드 해석기
def interpret_type_length(value):
    # 타입 코드 정의
    ether_types = {
        0x0800: "IPv4",
        0x0806: "ARP",
        0x86DD: "IPv6",
        0x8100: "VLAN Tagged",
    }

    if value >= 1536:  # 0x0600 이상
        protocol = ether_types.get(value, f"Unknown (0x{value:04X})")
        return f"타입 필드: {protocol}"
    else:
        return f"길이 필드: {value} 바이트"

# FCS (CRC-32) 간단 검증
def verify_fcs(data, received_fcs):
    # CRC-32 계산 (간소화된 버전)
    import zlib
    calculated_fcs = zlib.crc32(data.encode()) & 0xFFFFFFFF

    if calculated_fcs == received_fcs:
        return "FCS 검증 성공: 데이터 무결성 확인"
    else:
        return "FCS 검증 실패: 데이터 손상 가능성"

print(interpret_type_length(0x0800))  # IPv4
print(interpret_type_length(46))       # 길이
print(verify_fcs("Hello Network", 0x12345678))

김개발 씨가 Wireshark로 네트워크 패킷을 분석하던 중 혼란에 빠졌습니다. 어떤 프레임에서는 타입/길이 필드가 "0x0800"으로 표시되고, 어떤 프레임에서는 "64"로 표시됩니다.

같은 위치의 같은 필드인데 왜 이렇게 다른 걸까요? 박시니어 씨가 그 비밀을 알려주었습니다.

"이 필드는 역사적인 이유로 두 가지 역할을 해요. 값의 크기에 따라 의미가 달라지죠." 이더넷에는 두 가지 형식이 있습니다.

하나는 이더넷 II(DIX) 형식이고, 다른 하나는 IEEE 802.3 형식입니다. 두 형식이 공존하면서 같은 위치의 필드가 다른 역할을 하게 되었습니다.

규칙은 간단합니다. 필드 값이 1536(0x0600) 이상이면 타입으로 해석하고, 1500 이하길이로 해석합니다.

타입으로 해석될 때, 이 필드는 상위 계층 프로토콜이 무엇인지 알려줍니다. 예를 들어 0x0800은 IPv4, 0x0806은 ARP, 0x86DD는 IPv6입니다.

수신 장치는 이 값을 보고 데이터를 어떤 프로토콜 스택으로 전달할지 결정합니다. 길이로 해석될 때는 뒤따르는 데이터의 바이트 수를 나타냅니다.

IEEE 802.3 형식에서는 별도의 LLC(Logical Link Control) 헤더가 프로토콜 정보를 담습니다. 현대 네트워크에서는 대부분 이더넷 II 형식을 사용합니다.

따라서 0x0800(IPv4)이나 0x86DD(IPv6) 같은 타입 코드를 주로 보게 됩니다. 이제 **FCS(Frame Check Sequence)**에 대해 알아봅시다.

FCS는 프레임의 맨 끝에 붙는 4바이트 체크섬입니다. CRC-32(Cyclic Redundancy Check) 알고리즘으로 계산됩니다.

송신 장치는 프레임의 목적지 MAC부터 데이터까지의 내용을 CRC-32로 계산해서 FCS에 넣습니다. 수신 장치는 같은 계산을 수행해서 받은 FCS와 비교합니다.

값이 다르면 전송 중에 데이터가 손상된 것입니다. 위의 코드에서는 타입/길이 필드를 해석하고 FCS를 검증하는 함수를 만들었습니다.

zlib 라이브러리의 crc32 함수를 사용해서 체크섬을 계산합니다. FCS 오류가 많이 발생한다면 물리적 문제를 의심해야 합니다.

케이블 불량, 커넥터 접촉 불량, 전자기 간섭 등이 원인일 수 있습니다. 김개발 씨가 정리했습니다.

"결국 타입/길이 필드는 값으로 구분하고, FCS는 택배의 파손 여부를 확인하는 검수 도장 같은 거군요!"

실전 팁

💡 - 대부분의 현대 네트워크는 이더넷 II 형식을 사용합니다

  • FCS 오류율이 높으면 물리적 계층(케이블, 포트)을 점검하세요

7. 토큰 링 참고

김개발 씨가 네트워크 역사에 대한 글을 읽다가 "토큰 링"이라는 단어를 발견했습니다. "이더넷 말고 다른 네트워크 방식도 있었나요?" 이더넷이 현재의 표준이 되기까지, 경쟁했던 기술들의 이야기가 궁금해졌습니다.

**토큰 링(Token Ring)**은 IBM이 1980년대에 개발한 LAN 기술로, 이더넷의 강력한 경쟁자였습니다. 네트워크를 링 형태로 구성하고, 토큰이라는 특별한 프레임이 순환하며 통신 권한을 부여하는 방식입니다.

충돌이 없어 안정적이지만, 이더넷에 밀려 현재는 거의 사용되지 않습니다.

다음 코드를 살펴봅시다.

# 토큰 링 vs 이더넷 시뮬레이션
class TokenRingNetwork:
    def __init__(self, nodes):
        self.nodes = nodes
        self.token_holder = 0  # 토큰 보유 노드

    def pass_token(self):
        # 토큰을 다음 노드로 전달
        self.token_holder = (self.token_holder + 1) % len(self.nodes)
        return f"토큰이 {self.nodes[self.token_holder]}에게 전달됨"

    def send_data(self, sender, data):
        # 토큰을 가진 노드만 데이터 전송 가능
        if self.nodes[self.token_holder] == sender:
            return f"{sender}가 데이터 전송: {data}"
        return f"{sender}는 토큰이 없어 대기 중"

# 토큰 링 네트워크 시뮬레이션
network = TokenRingNetwork(["PC1", "PC2", "PC3", "PC4"])
print(network.send_data("PC1", "Hello"))
print(network.pass_token())
print(network.send_data("PC2", "World"))

어느 날 김개발 씨가 회사 창고에서 오래된 네트워크 장비를 발견했습니다. "Token Ring Adapter"라고 적혀 있었습니다.

호기심이 생긴 김개발 씨는 박시니어 씨에게 물었습니다. "선배, 토큰 링이 뭔가요?

이더넷이랑 다른 건가요?" 박시니어 씨가 추억에 잠기며 말했습니다. "아, 그거 옛날에 IBM이 만든 네트워크 기술이야.

한때는 이더넷의 강력한 경쟁자였지." 토큰 링은 이더넷과 완전히 다른 방식으로 동작합니다. 이더넷은 CSMA/CD(Carrier Sense Multiple Access with Collision Detection) 방식을 사용합니다.

쉽게 말해 "일단 말하고, 충돌하면 잠깐 기다렸다가 다시 말하기"입니다. 마치 회의실에서 여러 사람이 동시에 말하려다 겹치면 잠시 멈추고 다시 시작하는 것과 같습니다.

반면 토큰 링은 토큰 패싱(Token Passing) 방식을 사용합니다. 네트워크에 "토큰"이라는 특별한 프레임이 돌아다니고, 토큰을 가진 장치만 데이터를 보낼 수 있습니다.

마치 발언권을 가진 사람만 말할 수 있는 회의와 같습니다. 토큰 링의 장점은 명확했습니다.

첫째, 충돌이 없습니다. 토큰을 가진 장치만 전송하므로 데이터 충돌이 원천적으로 불가능합니다.

둘째, 예측 가능한 성능을 제공합니다. 각 장치가 토큰을 받는 시간을 예측할 수 있어 실시간 애플리케이션에 유리했습니다.

하지만 치명적인 단점이 있었습니다. 첫째, 복잡하고 비쌌습니다.

토큰 링 장비는 이더넷 장비보다 훨씬 비쌌습니다. 둘째, 확장성이 떨어졌습니다.

새 장치를 추가하려면 링을 끊어야 했고, 장치 하나가 고장 나면 전체 네트워크가 멈출 수 있었습니다. 위의 코드에서는 토큰 링 네트워크를 간단히 시뮬레이션했습니다.

토큰을 가진 노드만 데이터를 전송할 수 있고, 토큰은 순서대로 다음 노드에게 전달됩니다. 1990년대에 스위치드 이더넷이 등장하면서 상황이 바뀌었습니다.

스위치가 충돌 도메인을 분리해주면서 이더넷의 충돌 문제가 사실상 해결되었습니다. 더 싸고 더 빠른 이더넷 앞에서 토큰 링은 점점 시장을 잃어갔습니다.

결국 2000년대 들어 토큰 링은 거의 자취를 감추었습니다. IBM도 더 이상 토큰 링 제품을 만들지 않습니다.

하지만 토큰 패싱이라는 개념 자체는 산업용 네트워크나 일부 특수 환경에서 여전히 사용됩니다. 김개발 씨가 오래된 어댑터를 내려놓으며 말했습니다.

"기술의 흥망성쇠가 이런 거군요. 좋은 기술이 항상 살아남는 건 아니네요." 박시니어 씨가 고개를 끄덕였습니다.

"맞아. 생태계와 가격 경쟁력도 중요하지."

실전 팁

💡 - 토큰 링의 개념은 FDDI(광섬유 분산 데이터 인터페이스)에서도 사용되었습니다

  • 현대 산업용 네트워크 중 일부는 여전히 토큰 기반 방식을 사용합니다

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#Network#Ethernet#Frame#MAC주소#네트워크기초#CS

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.

함께 보면 좋은 카드 뉴스