Ethereal TCP/UDP 3,4,5

3. TCP(Transmission Control Protocol)

 3.1 Ethereal TCP

 3.2 TCP 연결

 3.3 TCP Header

 3.4 TCP 연결해제

 3.5 TCP Checksum 계산

4. UDP(User Datagram Protocol)

 4.1 Ethereal UDP

 4.2 UDP Header

 4.3 UDP Checksum 계산

5. Reference




3. TCP(Transmission Control Protocol)

 3.1 Ethereal TCP


 아래 그림은 TCP 프로토콜을 캡쳐한후 IP프로토콜에 대한 정보속에 TCP 프로토콜임을 명시한 부분을 보여주고 있다. 0x06은 TCP를 나타냄을 알 수 있으며 UDP의 경우 0x11이며 프로토콜마다 다른 값을 갖고 있어 구분됨을 보여준다.

IP Header 에서 TCP 명시




 3.2 TCP 연결

 아래 그림은 Capture Options의 Capture Filter에서 TCP만을 캡쳐하도록 설정한후 google.co.kr에 접속하여 획득한 패킷 캡쳐 화면이다.


핸드쉐이크(handshake) : SYN → SYN/ACK → ACK




 위 그림에서 ①번 부분은 SYN → SYN/ACK → ACK로 이어지는 3웨이 핸드쉐이크(3way handshake) 과정을 보여주며 정상적인 상태로 접속이 이루어짐을 보여주고 있다.

  핸드쉐이크과정을 보여주며 ②번 부분은 첫 프레임에서 목적지와 출발지의 Physical Address를 나타내고 있다. 만약 자신의 Physical Address와 IP등을 확인하려면 windows일 경우 명령프롬프트에서 “ipconfig /all" 명령으로 확인 가능하다.

 ③번부분은 ②번에서 선택한 Destination Physical Address 에 대한 16진코드가 어디에 위치하고 있는지 표시해주며 오른쪽은 아스키코드로 표현했을때의 캐릭터도 표시하여 준다.


 TCP 헤더를 보기 위해 ③번부분을 확대하여 헤더별로 구분하였다.

Packet에 포함된 헤더들



 처음 이더넷 헤더에선 목적지와 출발지의 Physical Address와 이더넷 유형이 IP(0x0800)임을 나타내고 있으며 그 다음 IP 헤더가 나온다. ip 헤더의 마지막 8바이트는 출발지와 목적지의 IP 주소를 나타내고 있다.



 3.3 TCP Header

 그 다음 TCP 헤더를 보여주고 있으며 기본 구조는 아래의 그림과 같다.


TCP Header 구조

SRC PORT : 송신쪽 포트번호

DEST PORT : 목적지 포트번호

SEQ: 송신용 순서 번호

ACK: 응답 확인 번호

HLEN

Reserved

Code Bit

Window size

U

R

G

A

C

K

P

S

H

R

S

T

S

Y

N

F

I

N

CheckSum

Urgent Pointer

Option

Data


 각 헤더의 옵션들은 길이가 정해져 있으며 Ethereal을 통하여 포커스를 이동하여 각각의 값과 설명을 볼 수 있다. 다음 표는 TCP Header 각각의 옵션에 대한 설명이며 Option과 Data는 그 길이가 유동적이다.

TCP Header 설명

필드명

비트수

내용

SRC PORT

16

송신쪽 포트 번호

DEST PORT

16

목적지 포트 번호

SEQ

(Sequence Number)

32

송신쪽이 보내려 하는 데이터 스트림의 단위를 나타내는 순서 번호

ACK

(Acknowledgement number)

32

다음번에 자신이 수신할 때 상대방이 보내야 할 송신용 순서 번호를 가지고 있음

HLEN

(Header Length)

4

TCP 헤더의 길이

RESERVED

6

나중에 확장을 위해 준비해둔 필드

CODE BIT

6

Contrl flag 또는 제어 비트라고 하며 6가지의 제어값을 가지며 ‘1’ 이 지정되면 다음과 같은 의미를 가진다. 왼쪽에서 부터의 필드값을 살펴보면..

URG

(Urgent Flag)

긴급하게 처리해야 하는 데이터가 들어 있다는 뜻

ACK

(Acknowledgement Flag)

응답확인 번호를 사용한다

PSH

(Push Flag)

TCP 가 받은 데이터를 바로 윗층 어플리케이션에게 보낸다.

RST

(Reset Flag)

어떤 원인인지 재전송을 해도 통신이 회복되지 않는 경우 일방적으로 TCP의 가상회선을 끊는 것을 의미한다.

SYN

(Synchronize Flag)

가상회로를 확립할 때 사용한다. 순서 번호를 이 TCP헤더에 나타난 송신용 순서 번호로 초기화 한다.

FIN

(Fin Flag)

송신쪽이 보낸 데이터가 종료 되었다는 것을 나타낸다. 그러나 수신은 계속 가능한 상태이다. 정상종료인 경우 끊기를 요청하는 쪽이 먼저 FIN을 지정한 TCP로 종료 요청을 통지한다. 받은 쪽에서는 종료 처리를 하고 FIN을 지정한 TCP헤더를 되돌려주어서 모든 처리를 종료 시킨다.

WINDOW

16

ACK에 나타난 SEQ번호에서부터 어는 정도의 데이터를 수신할 수 있는지를 알려준다

CHECKSUM

16

송신쪽은 TCP허위 헤드를 만들어 첵섬을 계산해서 이 필드에 넣어 전송하며, 수신측에서는 다시 같은 형태의 허위헤드를 만들어 책셈을 계산한뒤 제대로 데이터가 수신되었는 확인한다.

URGENT POINTER

16

긴급 처리해야 하는 데이터가 들어 있는 데이터를 가리키는 포인로 취급된다. TCP헤드 뒤에 추가된 데이터의 앞부분(송신용 순서 번호를 나나태는 장고)으로부터 이 긴급포인터에 나타나 수치 만큼의 바이트가 데이테로 처리된다.

OPTION

유동

통신의 세부 사항을 조정하기 위해 사용된다. 일반적으로 거의 사용하지 않으며 전체길이가 32비트의 배수가 되도록 지정해야 한다.

DATA

유동

실제 데이터


여기서 주의할점은 헤더의 길이를 나타내는 HLEN이며 word 단위를 나타낸다. 그러므로 byte로 나타나면 4를 곱하여하며 Ethereal에선 byte단위로 설명하므로 유의해야한다. 또한 HLEN과 Reserved, Code bit부분은 순서데로 연결되어지며 16bit이다. 그중 HLEN은 4bit를 차지하며 Reserved는 향후 사용될지도 모름을 감안하여 예약된 공간이며 6bit를 차지하고 Code bit가 6bit를 차지한다. Code bit는 Control bit(제어비트)라고도 하며 패킷의 중요한 정보를 뜻한다. Ethereal에서는 위에 명시된 6가지의 Code bit 외에 예약된 공간에 있는 2개의 bit를 더 설명하고 있다. 그것은 CWR(Congestion window reduced)와 ECE(ECN-Echo)이다. 이것은 사용되지 않고 있다. 정의된 바로는 ECN(Explicit Congestion Notification)이라 하여 실제 3bit로 정의되어있으며 NS(Nonce Sum) 1bit와 CWR(Congestion window reduced) 1bit, ECE(ECN-Echo) 1bit로 이루어진다. 하지만 사용되어지지 않으며 Reserved는 zero로 채워진다.


아래 그림은 HLEN과 Reserved, Code bit부분에 대한 보충설명을 위한 그림으로 검은 타원으로 표시한 부분이 HLEN, Reserved, Code bit부분이며 Reserved와 Code bit는 bit 단위로 봐야함을 나타내고 있다.

HLEN, Reserved, Code bit
TCP Code Bit Flag


 Flags 안쪽의 여러 가지 제어비트들은 각각 활성화돼 있을 경우 다음과 같은 의미를 지니게 된다. 여기서 ( )안의 숫자는 6bit를 10진수로 바꿨을때의 값이며 filter 사용시 "tcp.flag==16"이라한다면 tcp의 flag값이 16인 Ack를 갖는 패킷만을 필터링한다.

       ·Urgent : 긴급 포인터의 필드가 유효하다(32)

       ·Ack   : 수신 데이터의 일련 번호 필드가 유효하다. 보통 데이터가 정확히 수신측에 도착한 것을 의미한다(16).

       ·Push   : 플러쉬(flush) 동작에 의해 송신된 데이터임을 나타낸다(8).

       ·Reset : 접속을 강제적으로 종료하는데, 이상 종료시에 쓰인다(4).

       ·Syn   : 송신측과 수신측에서 일련 번호를 서로 확인하면서 이 제어비트로 접속 동작을 나타내게 된다(2).

       ·Fin   : 접속의 정상적인(타임아웃 등에 의한) 종료를 나타낸다(1).



 3.4 TCP 연결해제

 TCP의 연결해제는 FIN -> ACK/FIN -> ACK 형식으로 이루어지며 telnet과 같이 명시적인 해제방법 - Logout과 같이 - 을 사용할 경우 해제되는 과정을 명확히 관찰할 수 있다.

TCP 연결해제 캡쳐

TCP 연결해제 캡쳐



 위의 그림은 TCP의 연결해제 과정을 패킷 목록에서 보여주고 있으며 이것은 telnet에 대한 sample이다. 이 sample은 Ethereal 샘플 캡쳐 페이지(http://wiki.ethereal.com/SampleCaptures)에서 쉽게 구할 수 있다.



 3.5 TCP Checksum 계산

 Checksum은 전송된 패킷의 오류검사를 위한 부분으로 프로토콜마다 그 값을 갖고 있으며 TCP Header의 경우 16bit를 차지하고 있다. 여기선 Checksum의 계산법에 대해 알아 보도록 하겠다. 우선 Checksum의 계산법을 알기 위해선 2가지의 헤더를 알아야 한다. 하나는 TCP의 원래 헤더 구조이며 다른 하나는 Checksum의 계산을 위한 논리적인 가상 헤더이다. Pseudo Header라고하며 UDP에서도 Checksum계산시 UDP의 Pseudo Header를 사용한다. 우선 두개의 헤더를 보면 다음과 같다.


TCP Header Format



 이것은 위에서 봤던 TCP의 헤더를 나타낸다. 다음은 TCP의 Pseudo Header의 구조이며 가로는 언제나 32bit를 나타낸다.

TCP Pseudo Header





 Pseudo Header는 IP 헤더에 있는 Source Address(ip)값과 Destination Address(ip)를 사용하며 zero영역은 8bit만큼 0으로 채우며 PTCL은 protocol의 약자로 프로토콜 종류를 나타내는 값을 넣으면 된다. TCP의 경우 0x06을 사용한다. TCP Length는 TCP 헤더의 Data offset(HLEN)값이 해당된다. 여기서 주의할 점은 TCP의 길이는 헤더에서 word단위로 표시된다. 그러므로 byte단위로 바꾼후 이를 다시 16진수로 변환하여 계산해야 한다. 예를 들어 TCP헤더에서 길이가 5로 나타나있다면 이는 word단위이므로 4를 곱하여 byte단위로 하면 20(byte)가 된다. 이것을 다시 16진수로 바꾸면 0x14가 되며 이값을 Checksum에 사용한다.


 Checksum의 계산방법은 간단하다. 16bit단위로 모두 더해주면 된다. IP 헤더에서의 Checksum과의 다른점은 IP 헤더에선 IP 헤더의 값만을 갖고 Checksum을 계산하지만 TCP와 UDP에서는 헤더뿐만이 아니라 그 뒤에 붙어있는 data의 값도 포함하여 계산한다. 좀 더 확실한 계산을 위하여 아래 예제를 보겠다.


TCP Packet


 이것은 임의의 TCP 패킷을 Ethereal에서 선택한것이며 빨간색 네모로 표시한 부분은 Checksum 계산에 사용됨을 나타낸다. 위에서 본 TCP 헤더와 Pseudo 헤더 및 그에딸려있는 data 값을 모두 더하면 된다. 주의할점은 16bit단위로 더해지므로 16진수 4자리씩 끊어 더해주면 된다. 또한 Checksum을 계산하는 것이기 때문에 헤더의 Checksum값은 계산에 포함하지 않는다. 그림 아랫부분에 보면 16진수로 나타나있는 부분중 흰색글자에 녹색배경으로 되어있는 부분이 TCP 헤더이며 마지막부분에 0x46과 0x4f는 Checksum값이므로 계산에 포함되지 않는다.

Checksum 계산


 계산을 위해 헤더모양으로 정렬을 하였다. 위의 빨간 박스에 있는 값들은 TCP 헤더의 값이다. 10 E0은 소스포트 00 50은 목적지 포트, BB 94 90 EA는 시퀀스 넘버 순으로 순서대로 정렬하였으며 아래에 있는 빨간 박스는 Pseudo 헤더의 값이다. 맨 마지막의 00 14가 붉은색으로 표시된건 TCP의 길이값을 word에서 byte로 바꾼후 16진수로 변환되었음을 기억하기 위해서이다. 이 패킷은 뒤에 추가적인 data가 없기 때문에 헤더값만이 사용되지만 만약 data 값이 뒤에 있다면 계산에 포함시켜야 한다. 이제 이 값들을 모두 더한다. 16bit 계산이기 때문에 4자리의 수로 계산하면 된다.


 TCP 헤더의 합은 10E0+0050+BB94+90EA+7789+537F+5010+4470 = 2BD36이며,

Peudo 헤더의 함은 3B0D+24F4+42F9+5963+0006+0014=FC77이다. 그러므로 총 합은 2BD36+FC77=3B9AD이다.

 여기서 Carry 3이 발생한다. 발생한 캐리값은 모두 더해주면 된다. 그러므로 B9AD+3=B9B0이며 마지막으로 1의 보수를 취하면 Checksum값을 구하게 된다. 그러므로 464F를 얻을수 있으며 TCP 헤더의 Checksum값으로 있는 464F값과 일치함을 알 수 있다. 그러므로 이 패킷은 correct함을 알 수 있으며 Ethereal에서는 자동으로 계산되어 패킷이 정상임을 표시해준다.



4. UDP(User Datagram Protocol)

 4.1 Ethereal UDP

UDP 패킷 캡쳐




 위의 그림은 Capture Option의 Filter에서 “udp"만 캡쳐하도록 필터를 설정한 후 google.co.kr 사이트에 들어갔을 때 잡힌 DNS 프로토콜이다. DHCP는 작업중인 컴퓨터에서 유동아이피를 쓰므로 발생한 패킷이다. DNS 패킷을 클릭하면 이더넷 헤더와 IP 헤더 다음에 UDP 헤더가 보인다. UDP 헤더는 출발지 포트(16bit), 목적지 포트(16bit), 길이(16bit), 첵섬(16bit)의 순서데로 표시된다.



 4.2 UDP Header

 UDP 헤더의 구조는 TCP에 비해 매우 단순하며 아래와 같이 이루어져 있다.


UDP Header 구조


SRC PORT : 송신쪽 포트번호

DEST PORT : 목적지 포트번호

LENGTH

CheckSum

DATA

 LENGTH는 UDP헤더의 길이와 사용자 데이터의 길이를 더한 바이트 단위로 설정된다. 그러므로 Data가 없어도 최소한 8(byte)은 설정이 되어야 한다. 8을 설정하면 UDP의 헤더만 있고 사용자 데이터는 없다는 뜻이다.

Packet에서의 UDP Header


 위 그림은 실제 캡쳐한 패킷을 영역별로 구분한 그림이며 표시되지 않은 부분은 UDP 데이터 부분이다. (DNS 패킷 캡쳐)



 4.3 UDP Checksum 계산

 UDP의 CheckSum 계산은 TCP와 거의 같다. 아래 그림은 UDP 패킷을 캡쳐한 그림이며 붉은 박스로 표시된 부분은 Checksum 계산에 사용되는 부분을 표시하고 있다.

UDP Checksum에 사용되는 값들


 UDP도 TCP에서처럼 16bit 단위로 - 16진수로 4자리씩 - 계산하며 논리적인 가상헤더인 Pseudo Header를 사용한다. 아래 그림은 위에서 봤떤 UDP의 Header를 보여주고 있으며 당연히 Checksum값은 계산에 포함되지 않는다.

UDP Header Format


 UDP의 Pseudo Header의 구조는 아래 그림과 같으며 역시 Source IP와 Destination IP의 값은 IP 헤더에서 참조 되며 8bit는 Zero로 채워지며 IP 헤더에서 명시된 Protocol값인 0x11(UDP)를 사용하며 다음으로 UDP 길이를 사용한다. 만약 헤더뒤에 Data가 있다면 그 Data 값또한 표시되며 아래 그림에서 Optional Pad는 데이터를 그림과 같이 정렬했을 때 32bit를 채우지 못하고 빈다면 Zero로 채움을 나타낸다.


UDP의 Pseudo Header


 본격적인 UDP의 Checksum 계산을 위하여 위에서 본 UDP 패킷의 값을 사용하겠다.

UDP Header 값


 이 값을 계산하기 편하게 헤더구조와 같은 형태로 정렬하며 항상 16bit단위로 - 16진수로 4자리씩 - 계산됨을 기억하기만 하면 된다. 아래 그림은 이와같이 정렬한 모습이며 위의 붉은 박스부분이 UDP의 실제 헤더에 상응하는 값이며 Checksum 값은 사용하지 않으므로 0으로 채워놓았다. 아래 박스에서 검은선으로 나누어진부분의 윗부분이 UDP의 Pseudo Header의 값이며 아래에 있는 값들은 UDP 헤더의 뒤에 붙어있는 Data의 값들이다. 맨 마지막에 빈자리가 발생하여 Zero padding되었음을 강조하였다.


UDP CheckSum 계산


 이제 본격적인 계산을 해보면 UDP 헤더의 총합은 17DF+17DF+001C+0000=2FDA이며 Pseudo 헤더의 총합은 25FEE, 데이터의 총합은 49FB6이므로 총합은 49FB6이 된다. 16bit 단위의 계산이므로 캐리4가 발생함에 따리 캐리값을 다시 더해주고 1의 보수를 취하면 0x6045를 구할 수 있다. 계산시 TCP와 다른점은 TCP에서는 길이를 word로 표시했으며 4bit만을 사용하였다. 그래서 byte단위로 변환후 다시 16진수로 바꿔줘야 계산에 사용할 수 있었지만 UDP에서는 Length가 16bit를 차지하며 10진수로 바꾸면 바로 byte단위이므로 별도의 변환과정없이 그 값 그대로 Checksum 계산에 사용하면 된다.

 아래 그림은 Ethereal에서 보여주는 Checksum값과 그 값이 correct 함을 보여주고 있다.

Checksum correct


 우리가 한 계산에서와 같이 0x6045로 일치함을 볼 수 있다.


5. Reference

[ Ethereal 사용자 가이드 ] http://blog.naver.com/hushath/100013993495
[ Ethereal User's Guide ]  http://ethereal.secuwiz.com/docs/eug_html_chunked/
[ TCP ] http://www.ietf.org/rfc/rfc793.txt
[ UDP ] http://www.ietf.org/rfc/rfc768.txt
[ Ethereal sample capture ] http://wiki.ethereal.com/SampleCaptures
[ Ethereal을 이용하여 Packet Dump하기 ]  http://www.eztcp.com/Support/ethereal/ethereal_ko.html

'가지가지' 카테고리의 다른 글

UDP  (0) 2006.06.19
Motor Position (Modeling, PID, Root Locus)  (0) 2006.06.16
Qt 실행시 "세그멘테이션 오류" 잡기  (0) 2006.05.23
linux에서 DHCPd사용시 인터넷이 안될때 설정  (0) 2006.05.23
Sendmail 사용 - 2004년 2학기  (0) 2006.05.23
APM 설치 - 2004년 학기  (0) 2006.05.23
NTFS Mount  (0) 2006.05.22
Ethereal TCP/UDP 1,2  (0) 2006.05.21