OSI 계층별 TCP/IP 프로토콜 포맷
Data Link Layer (2계층)
- Ethernet Frame Format
맨 앞 2개(Preamble, SFD)는 physical layer header로서 wireshark에서 보이지 않는다.
wireshark에서 보면 Frame단위로 캡쳐를 하는것을 볼 수 있다.
MAC Header는 Destination MAC Address, Source MAC Address, EtherType부분이다. DATA는 3계층 이상으로 전달되는 부분이다.
Destination MAC Address: 도착지 맥 주소
Source MAC Address: 발송 맥 주소
EtherType: 데이터(페이로드)의 프로토콜이 어떤 것인지 지정 ( 0x0800-IPv4 0x86DD-IPv6 등등 종류: https://en.wikipedia.org/wiki/EtherType#Values)
Data: 3계층 이상으로 전달되는 부분으로서 최대 1500바이트이다. MTU(Maximun Transmission Unit)이 1500라고 할 수 있다. 하지만 jumbo frame을 사용하게 된다면 MTU가 9000까지 늘어난다. 또한 추가 설정에 따라 더 큰 MTU를 가질 수 있다.
Network Layer (3계층)
- ARP message format
arp(address resolution protocol)은 같은 네트워크에 있는 기기의 mac address를 ip로 구하는 프로토콜이다(IPv4에 사용).
http://www.tcpipguide.com/free/t_ARPMessageFormat.htm
Hardware Type는 지역 네트워크에서 사용하는 하드웨어의 종류이다. Ethernet은 0x01이다.
Protocol Type는 layer 3에서 사용되는 프로토콜의 종류이다. IPv4는 0x0800이다.
Hardware Address Length는 Ethernet에서 6이다(mac address 길이).
Protocol Address Length는 layer 3에서 사용되는 프로토콜의 주소 길이다. IPv4는 4다.
Opcode는 명령이다. 1은 ARP Request, 2는 ARP Reply다.
Sender Hardware Address는 메시지를 보내는 기기의 layer 2의 주소이다(Ethernet에서 mac address).
Sender Protocol Adddress는 메시지를 보내는 기기의 IP 주소이다.
Target Hardware Address는 메시지를 받는 기기의 layer 2의 주소이다(Ethernet에서 mac address).
Target Protocol Address는 메세지를 받는 기기의 IP 주소이다.
- IPv4 Packet format
IPv4 header의 크기는 20~60bytes다(4bytes단위이다).
https://en.wikipedia.org/wiki/Internet_Protocol_version_4#Packet_structure
Version은 항상 4(0100)이다.
Header Length는 헤더 크기(바이트)/4의 값이다. Header Length가 5면 header는 20bytes.
Total length는 header+data의 크기로 mininum 20bytes, maximun 65535bytes다. 이더넷 계층에서 data의 길이가 최대 1500bytes이기 때문에 1500초과한다면 fragment되어서 1500이 최대인것으로 착각할 수 있지만, ping 127.0.0.1 -l 60000하여 wireshark캡쳐한다면 total length 60028인 패킷이 보내진다. jumbo frame의 영향인것으로 추정된다.
Identification은 식별 필드이며 주로 하나의 IP 데이터그램의 프레그먼트 그룹을 고유하게 식별하는데 사용된다.
3bit의 Flags - 0bit: 항상 0이다. 1bit: Dont Fragment(0이면 라우터가 fragment할 수 있다. 1이면 fragment하지 말라는 뜻이다. ping -f를 하면 set된다.) 2bit: More Fragments(0이면 내가 마지막 fragmented packet이거나 unfragmented packet이다. 1이면 더 fragmented packet이 더 있다는 뜻이다.)
Fragment Offset은 packet이 fragment되었을 경우 현재 데이터가 어느 fragment인지 명시한다.
TTL(Time To Live)는 라우팅에서 몇번 전달될 수 있는지 남은 횟수이다.
Protocol은 Data가 어떤 프로토콜인지 명시한다. https://en.wikipedia.org/wiki/List_of_IP_protocol_numbers
Header Checksum은 header에 에러가 있는지 확인하는 비교대상이다. 만약 에러가 있다면 라우터는 해당 패킷을 버린다.
체크섬은 Data를 포함하지 않고 오직 헤더만을 계산한다.
unsigned short ipCsum(unsigned short *buf, int nwords)
{
unsigned long sum;
// 2바이트씩 나누어 헤더를 모두 더한다.
for (sum = 0; nwords > 0; nwords--)
sum += *buf++;
// 하위 2바이트에 상위 2바이트(올림)를 더한다.
sum = (sum >> 16) + (sum & 0xffff);
// 1의 보수로 만든다.
return (unsigned short)(~sum);
}
체크섬을 계산하는 방법. 2바이트씩 모든 헤더를 더하고, 올림을 더한다. 그리고 1의 보수로 만들어주면 체크썸이 된다. 체크섬이 계산된 헤더를 계산하면 결과가 0이 나온다. 헤더만 계산하기 때문에 nwords는 10이 거의 고정이다.
- ICMP format
IPv4 뒤에 붙는 포멧이다.
ICMP header의 크기는 8bytes다.
https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol#Datagram_structure
Type: request, reply등 어떠한 타입인지 명시한다. https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol#Control_messages
Checksum: 오류검사 값이다.
Transport Layer (4계층)
- UDP datagram format
UDP header의 사이즈는 8bytes다. http://www.tcpipguide.com/free/t_UDPMessageFormat.htm
Length는 header와 Data의 합을 bytes로 나타낸것이다.
Checksum은 udp pseudo header + UDP header + Data를 16비트 체크섬 계산한 값이다.
udp pseudo header는 진짜로 존재하지 않는, udp checksum만을 위해 가상으로 만든 헤더이다.
pseudo header의 UDP Length는 UDP header의 UDP Length를 그대로 가져와도 된다. 둘다 UDP header + Data의 길이이기 때문이다.
- TCP segment format
tcp header의 사이즈는 20~60bytes다. https://www.gatevidyalay.com/transmission-control-protocol-tcp-header/
URG비트: 긴급하다는 뜻을 보낼때 set
RST비트: tcp connection을 reset한다.
FIN비트: connection을 끝내고 싶을 때 set
Checksum: tcp pseudo header + tcp header + Data를 체크섬 계산한 값이다.
http://www.tcpipguide.com/free/t_TCPChecksumCalculationandtheTCPPseudoHeader-2.htm
pseudo header의 TCP Segment Length는 TCP header의 Header Length를 가져오면 안된다. tcp header + data의 길이값이기 때문에 따로 계산해주어야 한다.
Application Layer (7계층)