20130626

IP (Internet Protocol)헤더의 구조

0                                                                                  15 16                                                                               31

4bit

version

4-bit header

length

8-bit type of services

(TOS)

16-bit total length (in bytes)

16-bit identification

3-bit

flags

13-bit fragment offset

8-bit time to live

(TTL)

8-bit protocol

16-bit header checksum

20 bytes

32-bit source IP address

32-bit destination IP address

option (if any)

data

4bit version: 버전을 나타냄. 현재는 IPv4를 사용하고 있지만 보안상 문제가 많아 이를 해결하기 위해서 IPv6가 보편화 될것임

 

4bit header length:  데이터 영역을 제외한 순수 헤더의 길이. 아래에서 옵션은 일반적으로는 잘 사용되지 않는 부분이다.

                                그래서 대부분 5가 된다.(단위는 4byte이다. 4*5=20bytes) 만약 옵션이 사용될 경우에는

                                반드시 4byte씩을 채워야 한다.

 

8bit type of service(TOS): 앞의 3비트는 사용되지 않으며, 나머지 1비트는 0이다. RFC1349에서 권장하는 서비스별 TOS설정값이다

 

 

 ToS, TOS   (Type of Service)  

 

1. 개요

   ToS는 IP 패킷 헤더 내에 있는 8 비트 필드를 말하며, 요구되는 서비스 질의 유형을
   나타내는데 사용된다. 주로 IP 데이터그램라우터에서 어떻게 처리되어야하는지를
   정의하고 있다.


2. Type Of Service (TOS) Flag (8 bits) 세부내역

   ┌───┬───┬───┬───┬───┬───┬───┬────┐
     Precedence (우선순위)     D       T        R      C         0
   └───┴───┴───┴───┴───┴───┴───┴────┘
        0      1       2      3       4      5        6        7

  ㅇ 우선순위 설정용  (※오늘날에는 드물게 사용되고 있음)
     -  Bit 0-2 :  Precedence (우선순위 8단계)
       . 000 : Routine (Normal)
       . 001 : Priority
       . 010 : Immediate
       . 011 : Flash
       . 100 : Flash Override
       . 101 : Critical
       . 110 : Internetwork Control (OSPF에서 셋팅됨)
       . 111 : Network Control
  ㅇ TOS 설정용 
     -  Bit 3 :  Delay (지연)  ( 0 보통의 지연, 1 높은 지연 )
     -  Bit 4 :  Throughput (처리율)  ( 0 보통, 1 높음 )
     -  Bit 5 :  Reliability (신뢰성)  ( 0 보통, 1 높음 )
     -  Bit 6 :  Minimum Cost (최소비용)
  ㅇ 사용안함
    -  Bit 7   : 항상 0으로 셑팅됨
  

3. IP TOS 관련 권고

  ㅇ 의미

   TOS Value       Description                             Reference
   =========       =======================                 =========
     0000          Default                                 [RFC1349]
     0001          Minimize Monetary Cost                  [RFC1349]
     0010          Maximize Reliability                    [RFC1349]
     0100          Maximize Throughput                     [RFC1349]
     1000          Minimize Delay                          [RFC1349]
     1111          Maximize Security                       [RFC1455]

  ㅇ 각 프로토콜에 대한 권고

    Protocol            TOS Value              서비스 유형 
   ==========        ===============         =====================
    TELNET              1000                 (minimize delay)
    FTP  Control        1000                 (minimize delay)
    FTP  Data           0100                 (maximize throughput)
    TFTP                1000                 (minimize delay)
    SMTP Command phase  1000                 (minimize delay)
    SMTP DATA phase     0100                 (maximize throughput)
    Domain Name Service
      UDP Query         1000                 (minimize delay)
      TCP Query         0000
      Zone Transfer     0100                 (maximize throughput)
    NNTP                0001                 (minimize monetary cost)
    ICMP Errors         0000
    ICMP Requests       0000 
    ICMP Responses       
    Any IGP             0010                 (maximize reliability)
    EGP                 0000
    SNMP                0010                 (maximize reliability)
    BOOTP               0000

 

 

16bit total length: IP 데이터그램의 길이를 byte로 표시한다. 최대길이는 16비트이므로, 2의16제곱-1=65535bytes가 된다.

                             이 데이터를 넘게되면 데이터는 분해되어 전송된다. 이것을 단편화(Fragmentation)라고 부른다.

 

16bit Identification: IP가 중복되지 않는 값으로 IP 헤더를 구별할 수 있는 값이다. 이값은 계속적으로 증가되며 최대 65535까지

                               증가하고 이후 다시 처음으로 돌아와서 증가하기 시작한다.

 

3bit flages : 위에서 말했던 단편화와 관련이 있는 플래그이다. 먼저 첫 번째 플래그는 0이다. 두 번째 플래그는 DF(Don't Fragment)로,

                   단편화를 하지 않는다는 뜻으로 설정되는 비트이다. 세 번째 플래그는 MF(More Fragment)로 단편화를 한다는 뜻이다.

 

13bit fragment offset : MF되었을 때 그 위치 값을 나타내는 값이다. 쉽게 말하면 쪼개고 나서 다시 조립할 때 상대적인 위치를

                                    나타낸다. 각 조각난 패킷은 동일한 IP헤더를 가지게 된다. 다만 offset값만 다르다. 이 값은 후에 패킷을

                                    받는 쪽에서 재조립을 할 때 사용하기 위해서 패킷의 크기를 알려주는 값이 된다. 패킷이 조각나면 A, B는

                                    IP헤더의 MF값을 1로 설정한다. 그리고 마지막 패킷인 C는 0으로 설정된다. 이 값으로 패킷이 모두 도착했음을

                                    알리게 되는 것이다. 패킷을 쪼갤 수 있는 최소크기는 8bytes이다. 물론 최대크기는 자신의 자신의 MTU를

                                    넘지 못한다. 하지만 요즘의 많은 OS에서는 16바이트 이하로 패킷을 생성하면 전송되지 않는 경우를

                                    볼 수 있다. 전송하고 하는 데이터가 전송 버퍼보다 큰 경우 이 패킷을 적당한 크기로 분할하게 된다. 또는

                                    라우터를 지나면서 라우터가 자신의 능력(MTU)에 맞게끔 패킷을 다시 분할하기도 한다. 하지만 패킷이 너무

                                    많이 쪼개지면 통신량이 많아지고 효율성이 떨어지므로 문제가 될 수도 있다. 또한 중간의 조각난 패킷이

                                    손실되면 해당 데이터는 조립이 불가능하므로 나머지를 모두 버리는 상황이 발생할 수 있다. 패킷의 도착순서는

                                    알 수가 없다. 네트워크의 상황에 따라서 먼저 출발한 패킷이 나중에 올 수도 있기 때문이다. 모든 패킷이

                                    동일한 네트워크를 따라서 움직이지 않을 수 있다는 말이다.

 

-패킷의 조립과정: 패킷이 도착하면 오프셋 값을 이용하여 차례대로 패킷을 재조립하게 된다. 이때 ID(Identification)값은 동일하기

                            때문에 ID값에 대해서 오프셋 값을 적용하여 패킷을 재조립하는 과정을 거치게 된다.

<------504 Octet------>

<------504 Octet------>

<------504 Octet------>

IP헤더

IP헤더

Data Fragment A

IP헤더

Data Fragment B

IP헤더

Data Fragment C

(Identificaton은 모두 같고 offset으로 Data순서를 구분시킨다. 나머지 IP헤더는 같다. Data Fragment는 data.)

 

8bit time to live(TTL): 네트워크 상에서 얼마나 오랫동안 살아남을 수 있을지 결정하는 수치. 라우터 하나를 지날 때마다

                                    이 값은 1씩 줄어든다. 만약 값이 0이 되면 패킷은 버려진다. TTL 값이 0이 되면 그 결과를 ICMP패킷으로

                                    출발지에 되돌려준다. (라우터무한반복을 피하기 위한 TTL)

 

8bit Protocol: 수신할 상위 계층을 나타내기 위해서 사용한다. 이 필드가 사용되는 가장 큰 이유는 다중화의 지원이다. 한 IP 주소를

                      가진 컴퓨터에서 여러 가지 서비스를 동시에 하기 위해서 반드시 필요한 부분이 될 것이다. TCP는 6번, UDP는

                      17번, ICMP는 1번 값을 사용한다.

 

16bit header checksum: IP헤더에만 사용된다. 헤더를 구성하는 16개 비트각각의 1의 보수를 더한다. 그런 다음 합계의 1의 보수를

                                       구한다. 이 필드는 TTL필드가 라우터에서 감소되므로, 각 라우터에서 다시 계산되며 그에 따라 IP 헤더도

                                       수정된다(16개의 비트가 전체 IP헤더를 나타낸다)

 

32bit Source IP address, 32bit Destination IP address: 출발지와 목적지의 IP 주소값을 가진다. IP 네트워크가 무연결

                                                      네트워크이기 때문에 모든 IP 데이터그램은 출발지와 목적지 주소 값을 가지고 보내진다.

 

<RFC1349에서 권장하는 서비스별 TOS 설정값>

Application

Minimize

delay

Maximize

throughput

Maximize

reliability

Minimize

monetary

cost

Hex

value

Telnet/Rlogin

1

0

0

0

0x10

FTP

control

1

0

0

0

0x10

data

0

1

0

0

0x08

any bulk data

0

1

0

0

0x08

TFTP

1

0

0

0

0x10

SMTP

command phase

1

0

0

0

0x10

data phase

0

1

0

0

0x08

DNS

UDP query

1

0

0

0

0x10

TCP query

0

0

0

0

0x00

zone transfer

0

1

0

0

0x08

ICMP

error

0

0

0

0

0x00

query

0

0

0

0

0x00

any IGP

0

0

1

0

0x04

SNMP

0

0

1

0

0x04

BOOTP

0

0

0

0

0x00

NNTP

0

0

0

1

0x02 

 

 

 

 

 IP(Internet Protocol) Header


네트워크를 공부한다면 IP 데이터그램의 포멧은 기본적으로 알아두는 것이 좋다. 하나의 IP 데이터그램은

헤더 부분과 텍스트 부분으로 구성된다. 헤더는 20 바이트의 고정 부분과 가변 길이의 옵션 부분을 갖는다.

사용자 삽입 이미지

헤더는 빅엔디안(Big-endian) 순서로 전달된다. 즉, 왼쪽에서 오른쪽, Version 필드의 상위비트부터 전달된다.

(SPARC는 빅엔디안이고, 펜티엄은 리틀엔디안이다.) 따라서, 리틀엔디안 컴퓨터는 네트워크 상의 데이터 송신과

수신과정에서 데이터 변환이 필요하다. 엔디안에 대한 자세한 설명은 생략한다.

Version : 데이터그램이 속한 프로토콜 버전을 나타낸다. 현재 IPv4가 사용 중이며 IPv6로의 변화가 진행 중이지만

미래는 아직 불확실하다. IPv5는 실시간 스트림 프로토콜로 개발되었지만 현재는 사용 중이지 않다.


IHL : 헤더길이가 일정하지 않기 때문에 헤더의 길이를 나타낸다. 단위는 32비트 워드 단위로 최소값은 5, 최대값은

15이다. 최소값이 5인 것은 고정크기 20바이트를 가지고 있기 때문이다. 최대값이 15이므로 헤더는 60바이트로 제한된다.

따라서, 옵션은 40바이트까지 지정할 수 있다. (옵션은 4byte 단위로 늘릴수 있음)

Type of Service : 호스트가 서브넷에서 어떤 종류의 서비스를 원하는지를 나타낸다. 왼쪽부터 3비트는 우선권

(Precedence) 필드, 다음 3비트는 플래그(D, T, R)비트는 나타낸다. 우선권 필드는 0 ~ 7까지 우선권을 지정하고

플래그 비트는 라우터가 라우팅 할 때 중요시 해야할 선택요소를 나타내는 것으로 D(Delay), T(Throughput),

R(Reliability) Flag가 쓰인다. 하지만 현재 라우터는 이 필드를 무시하므로 거의 쓸모가 없다.

Total length : 데이터그램 내의 헤더와 데이터의 길이를 합한 값이 들어간다. 최대 길이는 65,535 바이트이다. 현재는

이 상한값이 적절하지만 미래의 기가비트 네트워크에서는 큰 데이터그램을 필요로 할 것이다.

Indentification : 일반적으로 데이터그램은 쪼개져(Fragmentation) 전송이 되는데 이 조각(Fragment)들이 어떤

데이터그램에 속하는지를 알려준다. 하나의 데이터그램은 모든 조각들이 동일한 Indentification 값을 가지고 있다.


DF(Don't Fragment) : 목적지 컴퓨터가 조각들을 다시 재조합할 능력이 없기 때문에 라우터에게 쪼개지(Fragment)

하지 말라고 알려주는 것이다. 하지만 현재는 대부분의 장비가 재조합이 가능하기 때문에 거의 필요없는 기능이다.


MF(More Fragment) : 조각난 데이터그램의 조각들은 마지막 조각을 제외하고는 이 비트를 설정한다. MF가 1이면 뒤에

조각이 더 있다는 것을 의미하고 MF가 0 이면 자신이 마지막 조각이라는 것을 의미한다. 모든 조각이 도착하면 수신측에

서는 재조합하여 상위 계층으로 보낸다.


Fragment offset : 데이터그램에서 도착한 조각이 어느 위치에 존재하는지를 나타낸다. 마지막을 제외한 모든 조각은

8 바이트의 배수여야 한다. 13 비트가 제공되므로 데이터그램당 최대 8192개의 조각이 있을 수 있고 최대 데이터그램

길이는 65,536 바이트가 된다.

Time to live : 이 필드는 패킷 수명을 제한하기 위해 사용하는 카운터이다. 시간은 초단위로 계수되며 최대 수명은

255초이다. 각 홉마다 감소되어야 하고 라우터에서 장시간 대기 했을 때에는 해당 시간만큼 감소된다. 하지만 시간은

구현하기 곤란한 이유로 현재는 홉수로 표현한다. 라우터를 지날 때 마다 홉수는 하나씩 감소하며 이 값이 0이 되면 해당

라우터에서 폐기하고, 경고 패킷의 경우는 원래 호스트로 돌려보낸다. 이것의 목적은 라우팅 테이블의 오류로 인해

패킷이 네트워크 상에서 영원히 떠돌아 다니는 것을 방지하게 된다.


Protocol : 네트워크 계층에서 데이터그램을 재조합할 때, 어떤 상위 프로토콜로 조합해야 하는지 알 필요가 있으므로

UDP 또는 TCP를 알려주기 위해 사용한다.


Header Checksum : 헤더의 값을 검증하기 위해 사용한다. 헤더의 오류를 검증하기 위해 사용하는데 헤더의 값 중에

Time to live의 값은 계속 변하게 되므로 매 홉마다 다시 계산하게 된다. 단, 트릭을 사용할 수도 있다.


Source address : 32비트(4바이트)로 데이터그램을 보낸 송신지 주소를 나타낸다.


Destination address : 32비트(4바이트)로 데이터그램을 받을 목적지 주소를 나타낸다.


Options : 원래 설계에서 소개 되지 않은 추가 정보를 포함하는 차기 프로토콜을 수용하고, 새로운 실험을 위해서나

헤더정보에 추가 정보를 표시하기 위해 설계되었다. 옵션은 가변길이로서 각각은 옵션을 확인할 수 있는 1바이트 코드로

시작한다. 다음은 5개의 옵션을 나타내지만 모든 라우터가 옵션을 지원하지는 않는다.


 

사용자 삽입 이미지

Security : 정보를 은폐할 것인지는 나타낸다.

 

Strict source routing : 송신측과 수신측까지의 완전한 경로를 일련의 IP 주소로 나타낸다. 데이터그램은 그 경로를 따라

 정확하게 전달된다. 이것은 라우팅 테이블이 변조되었거나 타이밍을 측정하는 동안 긴급 패킷을 보내는 시스템 관리자

에게 매우 유용하다.

 

Loose source routing : 패킷이 거쳐야 할 라우터의 목록을 명시하고, 그 순서를 명시하지만 도중에 다른

라우터를 거쳐 지나가는 것을 허용한다.

 

Record route : 경로상의 라우터가 IP 주소를 옵션 필드에 추가할 것을 나타낸다. 이것은 시스템 관리자가 라우팅

알고리즘에서 버그를 탐지하는데 사용한다.

 

Timestamp : 주로 라우팅 알고리즘을 디버깅하기 위해 존재하는 것으로 각 라우터의 32 비트 타임스탬프를 기록한다.

iphdr 구조체

/usr/include/netinet/ip.h 에 위치한다. 

 

   struct iphdr
      {

   #if __BYTE_ORDER == __LITTLE_ENDIAN
        unsigned int ihl:4;                             /* header length */
        unsigned int version:4;                       /* version */
   #elif __BYTE_ORDER == __BIG_ENDIAN
        unsigned int version:4;                       /* version */
        unsigned int ihl:4;                             /* header length */
   #else
   # error "Please fix <bits/endian.h>"
   #endif
        u_int8_t tos;                                     /* type of service */
        u_int16_t tot_len;                               /* total length */
        u_int16_t id;                                     /* identification */
        u_int16_t frag_off;                              /* fragment offset field */
        u_int8_t ttl;                                       /* time to live */
        u_int8_t protocol;                              /* protocol */
        u_int16_t check;                               /* checksum */
        u_int32_t saddr;                               /* source address */
        u_int32_t daddr;                               /* dest address */
        /*The options start here. */
      };

 

 

 

 

 

L2_IP() 함수

//L2에 IP를 분석하기 위한 함수

int L2_IP(void *vp)
{
       struct ip *stIP = vp;
 /*
    struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8    ihl:4,
version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
__u8    version:4,
ihl:4;
#else
  */          


 printf("IP Version      : IPv%d\n", stIP->ip_v); //IP version 출력

 printf("IP Header Size  : %d bytes\n", (stIP->ip_hl)*4); //IP Header Size 출력

 

 // 조건 연산자를 이용하여tos 해당 비트가 1이면 YES출력 0이면 NO 출력  
 printf("Type of service : LOWDELAY         %s\n", (0==( (stIP->ip_tos)& IPTOS_LOWDELAY ))? "NO":"YES" );

 printf("                  THROUGHPUT       %s\n", (0==( (stIP->ip_tos)& IPTOS_THROUGHPUT ))? "NO":"YES" );

 printf("                  RELIABILITY      %s\n", (0==( (stIP->ip_tos)& IPTOS_RELIABILITY ))? "NO":"YES" );

 printf("                  LOWCOST          %s\n", (0==( (stIP->ip_tos)& IPTOS_LOWCOST ))? "NO":"YES" );

 printf("                  MINCOST          %s\n", (0==( (stIP->ip_tos)& IPTOS_MINCOST ))? "NO":"YES" );

 /*
  * Definitions for IP type of service (ip_tos)
#define IPTOS_TOS_MASK      0x1E  //마스킹해야하는 해당 비트값 1 111   
#define IPTOS_TOS(tos)      ((tos) & IPTOS_TOS_MASK)
#define IPTOS_LOWDELAY      0x10  //
#define IPTOS_THROUGHPUT    0x08
#define IPTOS_RELIABILITY   0x04
#define IPTOS_LOWCOST       0x02
#define IPTOS_MINCOST       IPTOS_LOWCOST
  */

 printf("Total length    : %d bytes\n", ntohs(stIP->ip_len));        /* total length */

 printf("Identification  : %d\n", ntohs(stIP->ip_id));       /* identification */

 printf("FLAG            : More  Fragment   %s\n", (0==( (stIP->ip_off)& IP_MF))? "NO":"YES" );
 printf("                  Don't Fragment   %s\n", (0==( (stIP->ip_off)& IP_DF))? "NO":"YES" );
 //Flags는 Data가 쪼개져서 오는지를 알려줌, MF가 1이면 조각난 데이터가 더있다.


 /*
 #define IP_DF 0x4000           // dont fragment flag
 #define IP_MF 0x2000           // more fragments flag
 */ 
 

 printf("Fragment offset : %d\n", ntohs(stIP->ip_off) &IP_OFFMASK );// fragment offset field , 조각의 위치
  

 printf("Time to live    : %d\n", stIP->ip_ttl);//  time to live


 printf("Protocol        : ");//데이터그램을 재조합할 때, 어떤 프로토콜로 조합해야 하는지 알려줌

 switch(stIP->ip_p)
 {

  case IPPROTO_IP:
   printf("Dummy protocol for TCP\n");
   break;
  /*case IPPROTO_HOPOPTS:
  
   printf("IPv6 Hop-by-Hop options\n");
   break;*/
    
  case  IPPROTO_ICMP:
   printf("Internet Control Message Protocol\n");
   break;

   
  case  IPPROTO_IGMP:
   printf("Internet Group Management Protocol\n");
   break; 
   
  case  IPPROTO_IPIP:
   printf("IPIP tunnels (older KA9Q tunnels use 94\n");
   break;

  case  IPPROTO_TCP:
   printf("Transmission Control Protocol\n");
   break;
   
  case  IPPROTO_EGP:
   printf("Exterior Gateway Protocol\n");
   break;
   
  case IPPROTO_PUP:
   printf("PUP protocol\n");
   break;
   
  case IPPROTO_UDP:
   printf("User Datagram Protocol\n");
   break;
   
  case IPPROTO_IDP:
   printf("XNS IDP protocol\n");
   break;

  case IPPROTO_TP:
   printf("SO Transport Protocol Class 4\n");
   break;
   
  case IPPROTO_IPV6:
   printf("IPv6 header\n");
   break;
   
  case IPPROTO_ROUTING:
   printf("IPv6 routing header\n");
   break;
   
  case IPPROTO_FRAGMENT:
   printf("IPv6 fragmentation header\n");
   break;
   
  default :
   printf("Unknown\n");
  
  // printf("\n");
   break;

 } 

 

 return;
 
}

 


 

 

 

 

★ 리눅스 명령

 

   traceroute www.google.com

  위 명령과 주소로 PC와 주소간에 거치는 IP(게이트)를 확인할수 있다.

 

 

 

 

 

 VI Tip (alias)

 

 

 

 

_____ 수업자료 & 실습파일_________

 

pcap

 

pcap.c

________________________________

'스마트 컨트롤러 게시물' 카테고리의 다른 글

20130826  (0) 2013.08.26
20130627  (0) 2013.06.27
20130625  (0) 2013.06.25
20130624  (0) 2013.06.24
20130621  (0) 2013.06.21