CS/Computer network

Internet Protocol Version4 (IPv4)

ys_cs17 2022. 5. 24. 01:05
반응형

이전에 살펴본 내용과 동일하게 IP는 network layer에 속해 있다.

이전에 설명한 UDP 헤더는 위 이미지와 같이 구성이 되어 있고, 시작 포트 번호, 도착 포트 번호, 전체 길이, checksum으로 구성되어 있다.

network layer에 있는 얘는 datagram이라고 부르고, 이는 가변적인 옵션을 가지고 있다.

 

IP datagram

위 그림은 IP 헤더이다. 하나하나 씩 알아보자.

 

VER

버전 넘버를 의미하고, 4비트로 구성되어 있다.

HLEN

IP 헤더의 경우 옵션을 사용하게 되면 20 바이트부터 60 바이트까지 길이가 가변적으로 변하게 된다. 이를 HLEN을 통해서 알려준다.

4비트로 구성이 되어 있다. IP 헤더의 최대 바이트는 60인데, 최대 바이트가 할당되려면 4로 나누어서 15가 되고, 이를 HLEN을 토유 해서 표현한다.

Service type

IP에서는 잘 사용되지 않는다. 그냥 8 비트라는 것만 알고 있자.

Total length

Total length는 16비트로 구성되고, 헤더와 데이터 그램의 길이를 포함한다.

위 그림을 예시로 TCP, IP의 헤더의 합은 40 바이트이다. 여기에 1바이트 데이터가 포함되면 총 41 바이트가 된다. layer가 내려갈수록  frame이 붙게 되는데, 다른 layer에서는 이를 payload로 본다. 위 그림에서 length는 frame이다. 이는 최소한 46 바이트가 되어야 한다.

이를 맞추기 위해 강제로 padding을 붙어야 하는데, 받는 쪽에서는 padding 부분을 버려야 한다. 따라서 읽어야 되는 부분과 padding에 대한 경계를 알려주는 total legth가 필요하다. 16비트로 구성되어 있어 약 6만까지 표현이 가능하다.

Time to live

우선 얘부터 먼저 설명하겠다.

보통 ttl이라고 부르고, 라우터끼리 패킷을 전달하다 보면 무한 loop가 생길 수 있는데, ttl을 통해 maximum count를 적어서 이를 방지한다.

예를 들어 100이면 100개의 라우터가 지나가면 해당 패킷은 없어진다. 라우터를 건너갈 때마다 ttl 값은 -1이 된다. 

Protocol

 

같은 Network layer 안에 있는 ICMP, IGMP, OSPF도 IP 헤더를 가지고 있는데,  어떤 프로토콜로 전달할지 알려주는 field로 위 이미지와 같이 세팅한다.

Checksum

중간에 패킷이 변조가 되었는지 확인하는 field이다.

 

Example

만약 IP packet 앞 8비트가 01000010이 온다고 한다면?

처음 4개에 대한 비트를 통해 4 버전인 것을 알 수 있다. 그다음 4개 비트는 HLEN인데, $2 \times 4 = 8$이다. 하지만 헤더는 최소 20 바이트이기 때문에 이는 잘못된 비트이다.

만약 HLEN이 1000이면 32 바이트이기 때문에 옵션을 사용한 것을 알 수 있다.

 

45000028000100000102라는 비트가 들어왔다고 하자.

보통 16진수인 헥사 표현법을 사용하는데, 이는 4비트가 한 값으로 표현된 것이다.

우선 4 버전인 것을 확인할 수 있고, 여기서 얼마나 많은 hop을 지날 수 있는지는 ttl을 통해 알 수 있다.

9번째 바이트인 01이 ttl이고, 이를 통해 1개만 지날 수 있는 것을 알 수 있다.

 

 

 

Flag & Fragmentation  

MTU

MTU는 payload의 최대 값을 표현하는 것이고, 이는 physical network마다 다르다. 참고로 payload의 최솟값은 46이다.

 

헤더는 분할이 되지 않고, 오직 데이터 부분만 분할이 된다. 

Flag field는 총 3비트를 사용하고, 첫번째는 사용을 하지 않는다.

예를 들어 엄청 큰 택배 상자를 옮긴다고 하자. 우리는 중간에 승용차로 옮겨야 하는데, 이때 택배들을 분해해야 한다.

D는 분할을 하지 말라는 것이고, M은 분할해서 재조립할 때 원래의 packet으로 만들기 위해 사용한다. 1이면 뒤에 내용이 더 있다는 것이고, 0이면 마지막을 의미한다.

실질적으로 분할이 되는 과정이다. offset을 통해 순서 번호를 붙인다. 13비트만 할당했는데, 이는 8000으로 표현할 수 있다. ($$2^{3} \times 2^{10})

우리는 약 6만 여개를 표현해야 하는데, 이를 위해 곱하기 8, 나누기 8을 진행한다.

MTU는 헤더와 데이터가 포함된 값이고, 위 그림에서는 헤더 20을 더해 총 1420이다. 이는 데이터가 분할될 수 있는 최대 크기가 1420인 것을 의미한다.

위 그림과 같이 fragmentation field는 재조합 목적으로 사용된다. 1400 나누기 8할 값이 노란색 부분으로 들어간다. (각 0/8, 1400/8, 2800/8) 전체 길이는 1420이고, 마지막 패킷의 flag 값은 0인 것을 알 수 있다.

두 번째 layer를 통해 다른 네트워크에 가서 또 분할되는 모습을 볼 수 있다.

MTU가 820으로 분할 되는 것을 알 수 있다.

 

flag가 0 일 때 쪼개지면 마지막, 아니면 one packet인 것을 알 수 있다.

flag가 1인 경우 마지막은 아니다. 처음인지 중간인지는 모른다.

offset이 0이면 처음 패킷을 의미한다.

offset이 100인 경우 첫 번째 바이트는 8을 곱해서 800인 것을 알 수 있다. 하지만 이를 통해 마지막 번호는 알 수 없다.

HLEN가 5로 주어진 경우, 총길이는 20 바이트고, 이는 total length가 100인 경우 데이터는 80 바이트인 것을 알 수 있다.

따라서 마지막 바이트의 번호가 879인 것을 알 수 있다.

 

 

Option

 

첫 1바이트는 어떤 옵션을 쓸지 저장한다. 총 6개의 옵션이 존재한다.

특징에 따라 2개의 class로 나뉘게 된다. 첫 1비트는 copy를 할지 말지 결정하는데, 이는 MTU가 작은 곳으로 분할될 때 옵션을 가지고 갈 것인지 안 가지고 갈 것 인지 결정한다.

이를 보기 쉽게 시각화하면 옵션은 위와 같다.

 

(1) No operation option

Padding을 주는 옵션이다.

 

(2) Endo-of-option option

마지막에 패딩을 주는 용도이다.

 

(3) Record-route optipon

기본 헤더가 20바이트라고 가정하자. 빈 공간에 대해 포인터로 가리킨다. 맨 위 4, 8, 12, 16이 포인터이다.

이를 통해 본인의 주소를 적고, 옮길 때마다 포인터를 4씩 증가시킨다.

이를 통해 각 i번째 라우터의 ip 주소를 알 수 있고, 어디를 거쳐 왔는지 알 수 있다. 참고로 라우터는 최소 2개 이상의 주소를 가지고 있다.

 

(4) Strict-source-route option

위 그림과 같이 경로를 미리 적는 것이 strict-source-route option이다. 마지막 테이블로 최종적으로 어떻게 왔는지 알 수 있다. 물리적으로 네트워크를 테스트할 때 사용하고 일반적인 유저들은 사용하지 않는 옵션이다.

 

(5) Loose-source-route-option

다른 곳을 거쳐와도 상관이 없다는 것을 알려주는 옵션이다.

 

(6) Time-stamp option

Time-stamp option은 router가 packet을 전달할 때 출발 시간을 지정한 곳에 저장을 한다.

이 옵션은 크게 3가지 유형으로 나누어지고, 위 그림과 같이 시간과 본인의 주소를 적는다. 

위에서 언급한 record-router option과 비슷하지만 시간까지 추가적으로 적는다고 생각하면 된다.

언제 패킷이 보내졌는지 알 수 있고, sync까지 맞출 수 있다. packet은 ms 단위로 전송이 되는데, 오차에 대한 대략적인 정보를 해당 옵션을 통해 알 수 있다. 위 그림 테이블 맨 위에서 오른쪽 부분은 flag이고, flag에 따라 옵션의 종류가 달라진다.

Flag가 0인 경우 시간만 저장 한다.

Flag가 1인 경우에는 시간과 주소를 적는다.

Flag가 2인 경우에는 주소는 주어져 있고, 시간만 적으면 된다.

 

Loose-source-route-option, Time-stampe에 대한 header는 몰라도 되고, 개념에 대해서만 살펴보면 된다.

하지만 Record와 strict에 대한 내용은 header까지 주의 깊게 살펴봐야 한다.

 

Example

 

첫 번째 비트에 대한 의미는 fragmentation을 진행할 때 copy를 할지 안할지 결정한다.

1 인 경우 위 예시와 같이 copy를 진행한다.

 

두 번째 비트는 datagram control을 할 것인지, debugging and management control을 할 것인지 결정한다.

 

 

DNS

ping이라는 것을 다들 들어 본적 있을 것이다. 이는 domain까지 갔다온 rtt를 알려준다. ping을 통해 rtt가 어떻게 바뀌는지 측정하고, 이 domain을 쓰는 server가 network에 연결 되어있는지를 확인한다.

DNS 서버에 domain 이름을 넘겨주면 ip 주소를 알려준다. ip header에는 domain이 들어가지 않고, ip 주소가 들어간다.

따라서 network를 세팅하려면 ip 주소, subnet mask, next hop router address, DNS server address가 무조건 필요하다.

여기서 DNS 서버도 PK로 구성되어 있어, 만약 모르는 주소가 있으면 상위 DNS server에 물어본다.

 

리눅스 프로그래밍에서는 ping이라는 명령어를 제공한다.

pinr -R domain 명령어를 통해 record option을 주며 이를 통해 도메인 서버까지 거쳐가는 ip 주소들을 볼 수 있다.

traceroute domain 명령어를 통해 도메인까지 가는 router의 주소를 알 수 있고, rtt를 3번 구한다. 이때 rtt는 네트워크 상황에 따라 측정 시간이 다르기 때문에 계속 달라진다.

traceroute -g 명령어를 통해 loose source routing을 진행할 수 있다.

traceroute -G 를 통해서도 진행할 수 있고, 이는 보통 관리자들이 사용한다.

 

Checksum

IP에서의 checksum도 tcp와 비슷하다.

위 그림을 살펴보자. 보내주는 데이터가 1개의 비트라도 변경이 되었으면 탐지가 가능하다. 하지만 어느 부분이 오류가 생긴지는 모르고, 단지 있냐 없냐만 알 수 있다. tcp와 유사하게 보수값을 취해서 구하고, 받은 쪽에서도 보수값을 취해서 0이 나오면 참, 아니면 오류로 감지한다.

참고로 IP에서 checksum은 header에만 적용된다.

 

 

IP components

IP 구성 요소에 대한 도식화한 그림이다.

Header-adding module은 filed에 알맞는 값을 집어 넣어서 header를 넣어 준다.

Processing module은 전, 후로 패킷들이 들어오고 보내주는 역할도 한다.

IP 헤더를 붙어서 Forwarding module이 routing table을 참고해 fragmentation module에 보내고, 이를 진행할지 안할지 결정한다. 이것이 source IP에 있는 얘의 경로이다.

Router의 경우는 상대로부터 패킷을 받아 Forwarding으로 간후 fragmentation을 결정해서 간다.

최종 목적지에 있는 애들은 Reassembly로 가서 flag가 있으면 여기서 재조합을 하고 보내준다.

Reassembly module에 대해 살펴보자.

 

Reassembly module 

IP header에는 source IP, destination IP가 있고, flag와 관련된 애들은 위에서 2번째에 존재한다.

fragmentation option으로 인해 분할된 패킷들은 linked-list가 되고, 이를 offset을 통해 순서를 정한다. 하지만 time-out 값이 있어 packet loss가 발생하면 재조합을 할 수 없다. 다 완성이 되지 않은 packet들은 중간에 오지 않은 packet을 통해 알 수 있는데, 오지 않은 packet들이 도착을 하면 다시 재조합을 해서 다음으로 보낸다. 하지만 들어오지 않으면 재조합을 진행하지 못한다.

time-out이 지나도 오지 않는 packet이 존재하면 다 버리는 역할을 IP 프로토콜이 진행한다. Network layer에는 ACK과 같은 것을 사용할 수 없고, 오직 header만 보고 재조합해 상위 layer에 전달한다.

상대방은 전체 packet을 받고 재조립해 상위 layer에 전달하게 되는데, 이를 통해 중간에 없어진 packet이 발견이 되면, 보내는 쪽에서는 전부 다 다시 보내야 한다.

어떻게 보면 packet을 크게 보내는 것이 좋은 방법일 수도 있지만, packet loss가 발생하면 위험성이 더 커지게 된다. 따라서 tcp를 크게 만들지 않는 이유이다.

보통 LAN의 MTU가 1500바이트를 넘으면 fragmentation이 일어난다.

Reassembly module을 최종 목적지에서 진행한다. MTU 때문에 재조합을 할수도 있기 때문이다.

 

 

 

반응형