태그 : TCPIP

2009/01/28   IP Fragmentation
2009/01/27   ICMP
2009/01/26   ARP / RARP
2009/01/25   SLIP: Serial Line IP

IP Fragmentation

TCP/IP Illustrated Vol 1. 내용 요약.

IP Fragmentation은 전송 중 데이터그램이 MTU보다 큰 경우 어디에서나 발생할 수 있다. 한 번 분할된 패킷이 다시 분할되는 것도 가능하다. (인덱스가 아니라 오프셋을 기록하니까) 그리고 전송 계층(TCP, UDP 등)은 IP Fragmentation에 대해서 모른다. 이것은 분할된 부분 중 하나라도 유실된다면 전체 데이터그램이 다시 전송되어야 함을 의미한다. IP 자체는 타임아웃이나 재전송이라는 개념이 없으니 상위 계층에서 전체를 다시 보내게 되는 것.

IP 헤더의 Identification 필드는 각 데이터그램의 식별 번호를 담고 있으며, Fragmentation 되는 경우에도 이 Id값은 그대로 복사된다. Fragment Offset만 바뀔 뿐이다. Total Length는 분할된 크기에 맞춰서 조정된다. 분할하는 크기는 항상 8의 배수로 정렬된다. 물론 마지막 부분은 예외. 마지막 부분을 제외하고는 Flags 필드의 More Fragments 비트가 켜진다.

Don't-Fragment 비트를 켜놓고 ICMP Fragmentation Required 응답을 관찰하는 것으로 경로 전체의 MTU 값을 계산할 수 있다. 구형 장비가 아니라면 ICMP 에러 응답 자체에 MTU 값이 쓰여서 돌아온다.

IP 계층은 데이터그램의 분할된 조각을 받은 경우 타이머를 시작시켜야 한다. 보통 30초에서 60초 정도 시간을 두고 나머지 조각을 받는다. 만약 시간 내에 모든 조각이 도착하지 않으면 전부 버려진다. 이렇게 버려지는 경우 ICMP time exceeded during reassembly 에러가 발생할 수 있는데, 여기에도 조건이 있다. 첫번째 조각이 도착하지 않으면 어차피 전송자가 에러를 받아도 프로세스와 연관시키는데 필요한 전송 계층 헤더가 없기 때문에, 그냥 ICMP 에러 응답 없이 조용히 버린다. 조건이 맞더라도 BSD 계열은 그냥 무시하도록 구현한 경우가 많다고 한다.

RFC 815: IP Datagram Reassembly Algorithm

by xeraph | 2009/01/28 00:40 | 학술 | 트랙백 | 덧글(0)

ICMP

TCP/IP Illustrated Vol. 1의 관련 내용을 요약한 것이고 이하 전부 IPv4 기준 내용임.

ICMP 메시지 일반 형태
IP 헤더 20 + 타입 1 + 코드 1 + 체크썸 2 + 내용
  • ICMP 에러 메시지 보낼 때는 내용에 IP 헤더와 IP 데이터그램 첫 8바이트를 붙여서 보낸다.
  • ICMP 에러 메시지, IP 브로드캐스트/멀티캐스트 패킷, 링크 계층 브로드캐스트, 첫번째가 아닌 IP 프래그먼트, 출발지 주소가 단일 호스트를 지정하지 않는 경우는 ICMP 에러 메시지를 발생시키면 안 된다. (패킷 스톰 위험 -_-)
ICMP type / code / 설명
0 / 0 / echo reply
3 / 0 / network unreachable
3 / 1 / host unreachable
3 / 2 / protocol unreachable
3 / 3 / port unreachable
3 / 4 / fragmentation needed but don't-fragment bit set
3 / 5 / source route failed
3 / 6 / destination network unknown
3 / 7 / destination host unknown
3 / 8 / source host isolated
3 / 9 / destination network administratively prohibited
3 / 10 / destination host administratively prohibited
3 / 11 / network unreachable for TOS
3 / 12 / host unreachable for TOS
3 / 13 / communication administratively prohibited by filtering
3 / 14 / host precedence violation
3 / 15 / precedence cutoff in effect
4 / 0 / source quench
5 / 0 / redirect for network
5 / 1 / redirect for host
5 / 2 / redirect for type-of-service and network
5 / 3 / redirect for type-of-service and host
8 / 0 / echo request
9 / 0 / router advertisement
10 / 0 / router solicitation
11 / 0 / time-to-live equals 0 during transit
11 / 1 / time-to-live equals 0 during reassembly
12 / 0 / IP header bad (catchall error)
12 / 1 / required option missing
13 / 0 / timestamp request
14 / 0 / timestamp reply
15 / 0 / information request (obsolete)
16 / 0 / informatino reply (obsolete)
17 / 0 / address mask request
18 / 0 / address mask reply

여기부터 타입/코드는 위의 표를 참조하고 아래는 체크썸 이후 패킷 부분에 대해서만 기술함.

ICMP Address Mask Request and Reply

identifier 2 + sequence number 2 + subnet mask 4

identifier와 sequence number는 아무거나 원하는대로 쓰면 됨. 응답은 당연히 맞춰서 해야 하고. 디스크 없는 장비들이 서브넷 마스크를 얻어올 때 사용함. 이것 대신 BOOTP 프로토콜 사용할 수도 있음. 마스크 응답할 때 유니캐스트로 해야 하는데 고대의 장비 중에는 브로드캐스트하는 녀석도 있다고 함.

ICMP Timestamp Request and Reply

identifier 2 + sequence number 2 + 요청 보낼 때 타임스탬프 4 + 요청 수신한 시점의 타임스탬프 4 + 응답 전송할 시점의 타임스탬프 4

타임스탬프는 UTC 기준이고 지난 자정부터 경과한 시간을 밀리세컨드 단위로 계산한 값임. 요청 보낼 때 타임스탬프 - 요청 수신한 시점의 타임스탬프한게 음수가 나올 수도 있음을 유의할 것. 원래 수신 시점과 전송 시점 타임스탬프는 미묘하게 차이가 있어야 되는데 다들 무시하고 동일하게 쓴다고 함.

시간대까지 고려하더라도 아무튼 하루 정도 밖에 보정할 수 없음. 제대로 맞추고 싶으면 NTP 써야 함. 마지막으로 UTC가 아닌 값을 타임스탬프로 찍을 때는 최상위 비트를 켜서 UTC가 아님을 표시해야 함.

ICMP Port Unreachable Error

오류를 일으킨 IP 데이터그램의 헤더 20 + UDP 헤더 8

IP 헤더와 UDP 헤더를 내용에 포함해서 전송해주니까, IP 헤더의 프로토콜, UDP 헤더의 출발지/목적지 포트를 이용해서 실제 문제를 일으킨 유저 프로세스를 찾아 ICMP 오류를 보내주면 됨. UDP인데 connect 함수가 있는 이유가 이것임. connect 안 하면 ICMP 와도 그냥 씹고 버리는거고~

Ping: ICMP Echo Request and Reply

identifier 2 + sequence number 2 + 아무거나 데이터

유닉스는 identifier 부분에 프로세스 ID를 박고, sequence number는 echo 패킷 보낼 때마다 1씩 증가시킨다고 함. 응답 받을 때 identifier를 보고 유저 프로세스에게 다시 전달해주고, 유저 프로세스는 sequence를 보고 자기가 보낸 패킷에 대한 응답인지 확인한다. 데이터 부분에 타임스탬프를 박아놓으면, 에코 응답은 똑같이 복사해서 보내게 되어있으니 나중에 얼마나 시간이 소요되었는지 확인할 수 있다.

Traceroute: ICMP time exceeded and ICMP port unreachable

원래 IP Record Route 옵션으로 IP 헤더의 옵션 필드에 저장할 수 있긴 한데, 너무 옵션 길이를 박하게 줘서 지나간 라우터 주소를 최대 9개까지만 기록 가능하다. 단방향성은 대부분의 구현에서 에코 쓰면 옵션도 복사를 해주니까 별 문제가 안 되는데, 막상 돌아오는 경로를 담기엔 역시 옵션 길이가 너무 딸린다. 그래서 TTL을 이용하는 방식을 널리 쓰게 된 것이다.

TTL을 1부터 하나씩 늘려가면서 보내면 ICMP time exceeded 메시지가 날아오고, 최종적으로 호스트에 도착했을 때는 ICMP port unreachable 메시지가 날아오게 만들어서 경로를 식별한다. 물론 마지막에 ICMP port unreachable이 뜨게 하려면 거의 쓰일 가능성이 없는 높은 포트 번호(33435)를 찍어야 되고, 이 포트 번호도 하나씩 늘려가면서 요청과 응답을 연관시킨다. 응답을 프로세스로 연결하는 부분은 처음에 요청 보낼 때 출발지 포트 번호를 32768과 OR해서 만들어내는 것으로 해결한다.

IP Record Route 옵션을 쓰는 경우는 항상 밖으로 나가는 인터페이스 기준으로 IP가 기록되지만, TTL을 이용한 경우에는 항상 UDP 데이터그램이 도착한 인터페이스의 IP가 기록된다.

ICMP Redirect

새로운 라우터 IP 주소 4 + 원본 IP 헤더 + 원본 IP 데이터그램의 첫 8바이트

라우터로 들어온 패킷의 다음 경로를 살펴봤더니 들어온 인터페이스로 다시 나가야 되는 상황인 경우, 호스트가 라우터를 잘못 찍어 보낸 것이므로 호스트에게 ICMP Redirect 패킷을 보내준다. 호스트는 ICMP Redirect를 받으면 악성 패킷이 아닌지 몇 가지 확인을 해보고 라우팅 테이블에 경로를 추가한다.

4.4BSD는 ICMP Redirect 패킷을 수신하면 아래와 같은 기준으로 검사한다.
  • 새 라우터는 직접 연결된 네트워크에 있어야 한다.
  • 현재 라우팅 테이블을 이용했을 때 목적지에 대응하는 해당 라우터에서 온 패킷이어야 한다.
  • 원래 Redirect 목적이 다른 라우터를 이용하라는 것이니 자기 자신을 쓰라고 하는 패킷은 버린다.
  • 변경되는 경로는 indirect 경로이어야 한다. (indirect는 전송 시 IP 주소와 링크 계층 주소가 다른 것을 의미함.) 
ICMP Redirect는 라우터만 전송할 수 있으며 호스트에게만 전송한다. 라우터끼리 라우팅을 조정할 때는 별도의 라우팅 프로토콜을 이용해야지 ICMP Redirect를 쓰면 안 된다.

호스트는 관리의 귀찮음으로 인해 기본 게이트웨이만 설정하는 경우가 대부분인데, 다수의 네트워크가 물려있는 경우 ICMP Redirect로 호스트의 라우팅 테이블을 자동 조정할 수 있게 되니 네트워크 관리자 입장에서는 편한 것이라. 이 외에 ICMP로 라우터를 검색하는 방법이 또 있다.

ICMP Router Descovery (RFC 1256)

ICMP router solicitation message
미사용 4 (0으로 고정)

ICMP router Advertisement message
라우터 주소 수 1 + 항목 크기 1 (2로 고정) + 유효기간 (초 단위, 보통 30분) 2 +
{라우터 주소 4 + 선호도 4} 여러 개

선호도는 큰 값일수록 같은 서브넷의 다른 라우터보다 선호된다는 것을 의미하고, 0x80000000으로 쓰면 (최상위 비트 1) 기본 라우터로는 쓰지 말라는 의미임. 광고 주기는 450~600초 정도. 라우터 인터페이스를 다운시키는 경우에는 유효기간을 0으로 해서 전송하니 호스트는 이런 패킷을 받으면 라우팅 테이블에서 바로 삭제하면 된다. 호스트는 보통 부팅 후 3초 간격으로 3번 라우터 주소 요청 (solicitation)을 전송한다.

프라이머리와 백업 라우터가 있는 경우 프라이머리 라우터의 선호도 값을 크게 해놓으면 만사 오케이~

ICMP Source Quench Error

미사용 4 (0으로 고정) + IP 헤더와 원본 IP 데이터그램의 첫 8바이트

버퍼가 고갈되면 전송자에게 그만 보내라고 에러 메시지를 보낸다. 흐름 제어용. 1987년 나온 RFC 1009에서는 라우터의 버퍼가 고갈되면 Source Quench 에러를 반드시 보내도록 되어 있으나, 1993년 새로 나온 RFC에서는 라우터에서 Source Quench 에러를 내지 말도록 명시하고 있다. 네트워크 대역폭만 잡아먹고 비효율적인 방식인데다 혼잡 제어를 공정하게 할 수 없기 때문.
by xeraph | 2009/01/27 12:35 | 학술 | 트랙백 | 덧글(0)

ARP / RARP

나중에 구현 시 빨리 참조하기 위한 노트

이더넷 헤더 14바이트
목적지 MAC 6 + 출발지 MAC 6 + 타입 2
여기서 ARP에 해당하는 타입 번호는 0x0806, RARP의 경우 0x8035

ARP 요청/응답 28바이트
하드웨어 주소 타입 2 + 프로토콜 타입 2 + 하드웨어 주소 크기 1 + 프로토콜 주소 크기 1 + 오퍼레이션 2 + 전송자 이더넷 주소 6 + 전송자 IP 주소 4 + 목표 이더넷 주소 6 + 목표 IP 주소 4

오퍼레이션 이후의 부분은 이더넷과 IP 주소 매핑인 경우를 상정한 것임.
하드웨어 주소 타입은 이더넷 주소인 경우 1로 씀.
프로토콜 주소 타입은 IP 주소인 경우 0x0800으로 씀.

하드웨어 주소 크기는 이더넷 주소인 경우 6이 되고,
프로토콜 주소 크기는 IP 주소인 경우 4가 됨.

오퍼레이션 코드는 각각
  • ARP 요청 - 1
  • ARP 응답 - 2
  • RARP 요청 - 3
  • RARP 응답 - 4
BSD 계열의 경우 캐시된 항목은 20분 타임아웃 적용하고, 아직 수신 안 된 항목은 3분의 타임아웃을 적용함.

Gratuitous ARP는 부팅하고 나서 IP 주소 충돌 확인할 목적으로 주로 사용됨. 전송자 주소와 목표 주소를 자기가 원하는 IP로 써서 확인함. 응답이 없으면 아무도 안 쓰는 것이므로 안심하고 쓰는 것임.

Proxy ARP는 별로 중요하지 않으므로 생략.

RARP 서버는 보통 유저 프로세스로 구현되는데, 이더넷 프레임 타입이 0x8035여서 특별한 방법을 쓰지 않으면 커널에서 이런 패킷을 받아올 방법이 없음. 이럴 때 사용되는게 BSD Packet Filter (BPF), Sun's Network Interface Tap, SVR4 Data Link Provider Interface 같은 부류.

사용 예로는 디스크 없는 장비에서 NIC 롬에 쓰인 MAC 긁어서 RARP 요청 보내고, RARP 응답으로 IP 받은 다음, TFTP로 부트 이미지를 읽어오는 경우를 생각하면 됨.
by xeraph | 2009/01/26 00:13 | 학술 | 트랙백 | 덧글(0)

SLIP: Serial Line IP

SLIP은 Rick Adams가 4.2BSD에 구현하면서 세상에 나왔다. 내장형 시스템에서는 RS-232 시리얼 포트를 흔하게 볼 수 있는데, 이들을 인터넷에 연결할 때 SLIP 프로토콜이 사용된다. 규칙은 매우 간단하다.
  1. 프레임은 END (0xc0) 제어 문자로 끝난다.
  2. 프레임은 END (0xc0) 제어 문자로 시작한다. 이는 대부분의 구현에서 채택하고 있는 방식으로, 앞 프레임에 노이즈가 발생했을 때 쉽게 잘라서 버릴 용도로 넣는 것이다.
  3. IP 데이터그램에 END 제어 문자가 포함된 경우 0xdb 0xdc로 치환한다. 0xdb는 ESC 제어 문자이다.
  4. IP 데이터그램에 ESC 제어 문자가 포함된 경우 0xdb 0xdd로 치환한다.
특징은,
  1. 타입 필드가 별도로 없기 때문에, 시리얼 라인에서 SLIP을 쓴다면 그 외의 다른 프로토콜을 동시에 사용할 수 없다.
  2. 체크썸이 별도로 없기 때문에, 상위 계층은 오류를 탐지하고 버리는 로직이 필요하다.
이 외에 Compressed SLIP이라 해서 CSLIP 프로토콜도 있다. 보통 시리얼은 19200bps 수준의 느린 속도를 보이는데 반해 TCP/IP 헤더를 다 합치면 40바이트나 되기 때문에 오버헤드가 상당히 크다. CSLIP은 40바이트 헤더를 3이나 5바이트로 줄여준다. 헤더 필드를 뽑아내서 단말이 직접 최대 16개의 연결까지 상태를 관리하도록 한 것이다. RFC1144 참조

TCP/IP Illustrated, Vol1 24~25 내용을 정리함.
by xeraph | 2009/01/25 18:11 | 학술 | 트랙백 | 덧글(0)
<< 이전 페이지 다음 페이지 >>