650px-Ethernet_plug_grey.png         



안녕하세요.

 

뉴페이스 유형석입니다.

 

이번시간에는 이더넷 패킷을 어떻게 까보는지 알아 봅시다.



1. 이유?


    아래에 오재경 이사님이 이더넷패켓 까서보기에 대해서 글을 올려 주셨습니다.

    하지만! 저는 글만 보고 머리속에 그려지지가 않기 때문에

    코딩을 할땐 어떻게 까야 될까 생각해봤습니다.


    하지만 초보자가 하기엔 쉽지 않죠!

    그래서 요즘 보고 있는 lwip 에서 필요한 부분만 뜯어봤습니다.


    그리하여 쓰게된 이더넷 패킷까기 입니다.


2. 구조체

    

    일단 패킷을 쉽게 까보기 위해서는 구조체로 만드는 것이 편합니다.


    자 이더넷 헤더를 일단 맹거 봅시다.


 // Ethernet Header
struct _eth_hdr
{
    u8     dest[6];
    u8     src[6];
    u16    type;
}__attribute__((packed));
typedef struct _eth_hdr ETH_HDR;

    목적지 MAC의 주소를 담기 위한 dest 배열

    시작지 MAC의 주소를 담기 위한 src 배열

    마지막으로 이더넷 타입을 위한 type 변수

    를 만들어 줬습니다.


    그리고 __attribute__((packed)) 는 이더넷 패킷 만들때 매우 중요합니다.

    __attribute__((packed)) 를 선언 하지 않고 패킷을 날릴 경우

    주소가 엉망이 되서 오는 경우가 발생 합니다.

    꼭! 써줍시다.


    그리고 typedef 로 구조체를 재정의 한건 뭐 안하셔도 상관은 없습니다.

    전 그냥 보기 좋게 하기 위해서 사용했습니다.


    그다음은 ARP 헤더입니다.


 struct _etharp_hdr {
    u16 hwtype;
    u16 proto;
    u8  hwlen;
    u8  protolen;
    u16 opcode;
    struct eth_addr shwaddr;
    struct ip_addr2 sipaddr;
    struct eth_addr dhwaddr;
    struct ip_addr2 dipaddr;
}__attribute__((packed));
typedef struct _etharp_hdr ETHARP_HDR;


    하드웨어 타입을 넣기 위한 hwtype 변수

    프로토콜 타입을 넣기 위한 proto 변수

    하드웨어 주소 길이를 위한 hwlen 변수

    프로토콜 주소 길이을 위한 protolen 변수

    ARP 요청 응답을 알려주는 opcode 변수

    shwaddr 과 sipaddr은 각각 보내는 곳의 하드웨어 주소와 아이피 주소

    dhwaddr 과 dipaddr은 각각 받는 곳의 하드웨어 주소와 아이피 주소


    그냥 ARP 헤더 형식대로만 맞춰 주면 됩니다.

    그리고 하드웨어 주소와 아이피 주소는 다시 구조체로 만들어져 있는데요.

    아래를 보시죠~

 
 struct eth_addr {
    u8 addr[6];
}__attribute__((packed));


    하드웨어 주소입니다.

    일반적으로 MAC주소이니 addr[6] 이 되겠습니다.


 struct ip_addr2 {
    u16 addrw[2];
}__attribute__((packed));


    요건 ip 주소입니다.

    u16으로 쪼개서 보내 줍니다.


    요래 만든 구조체를 선언해서 각각의 값에 원하는 값을 신명나게 넣어 주신 후

    날려주시면 되겠습니다~


    근데 어떻게 날릴지 모르겠다구요?

    값을 어떻게 넣어야 되냐구요?

    그건 다음시간에 이어지겠습니다~~


    아쉽지만 다음주에 뵈요~


    짧은 글 읽어 주셔서 감사합니다!

 

이미지 출처 : 위키피디아