어제
UDP를 이용해 데이터를 주고받는 프로그램을 만들었고

그 데이터를 덤프시킬 프로그램도 만들었었다.

이제 그 데이터를 분석해보겠다.


(어제 했던 Hello 데이터를 전달하는 UDP 패킷내용)


Hello 앞에 나오는 헤더부분을 살펴보자.
b'E\x00\x00!\x11\xf6\x00\x00\x80\x11\x9f\xf1\xc0\xa8\x03\xa5\xc0\xa8\x03\xef\xce\x89\xea`\x00\r\x9a2
(이건 오늘 실행시켜서 복사한 패킷헤더이다.)

\ (역슬래쉬)
\x 로 표시는 16진수 표시이다.

왜 어떤건 문자로 나오고 16진수로 나올까?
-> 문자로 나올수 있는 것은 문자로 나온다.
16진수 중에 문자로 표시할수 있는건 문자로 표시한다. (이것도 16진수)
(아스키 코드에 따라)

앞에 b라고 붙어있다. -> 실제 네트워크 스트림에 사용하는 데이터가 파이썬에서 맞지 않는다.
       -> 그래서 C에서 API를 가져온다.
       -> C언어가 쓰는 바이트타입을 가져온것이다.
       -> 그래서 다시 파이썬에 맞게 바꾸는 함수가 있는데,
           그건 - pack()
                  - unpack()
             함수이다.

이 함수들은 struct 모듈 안에 들어있다.


(unpack의 사용 모습 (파이썬공식홈페이지 출처))


hhl 표시  -> 각각 2바이트 2바이트 4바이트로 묶어서 출력하라는 뜻이다.

우리는 앞에부터 20바이트는 뺄것이다. 이 패킷은 IP헤더이기 때문에
20바이트 뒤부터 분석을 해볼 것이다.


(slice로 앞 20바이트는 잘라내는 모습)



(IP헤더는 떨어지고 UDP 패킷내용만 남은 모습)



여기서 unpack을 사용하지않고
list를 사용해 전부 hex 표시로 바꾸겠다.

* map() 함수 - 두번째 인자를 첫번째인자(함수)에모두 입력한다.
hex 또한 함수이기 때문에 지금 쓰는것은 두번째 인자를 모두 16진수의 수로 바꿔주는 것이다.

(hex 표시로 바꿔주는 코드)



(16진수로 표시되는 모습)



전부 16진수로 나오는 모습이다.

뒤에 다섯자리 '0x48', '0x65', '0x6c', '0x6c', '0x6f' 를 아스키코드에 대입하면
Hello 라고 우리가 보내는 데이터임을 알 수 있다.

그리고 데이터 앞자리 우리가 구한 UDP헤더의 내용이다.
['0xcc', '0xe8', '0xea', '0x60', '0x0', '0xd', '0x9b', '0xd3']

헤더에는 총 4개의 내용이 들어있다. (첫번째 부터)

1. Sorce Port Number (출발지의 포트번호) 
     ->2바이트 (출발지 포트)

2. Destination Port Number (출발지의 포트번호) 
     -> 2바이트 (도착지 포트)  '0xea', '0x60'  = ea60  = 60000
3. Length (길이) 
     -> 2바이트  = '0x0', '0xd  = 0d   =13  = 13바이트 
(헤더 8바이트, UDP데이터 5바이트) 13바이트가 맞다.

4. Checksum
     ->2바이트   검사용

-> 이런게 Protocol 프로토콜이다.
처음에는 데이터 Hello가 보내지는걸  봤는데 이제 Hello가 패키징 되면서 붙는 내용들을 확인한다.
그 과정중 하나가 UDP를 본것이다.

UDP 헤더의 내용은 4개 밖에 없다. -> 에러정정, Flow Control 등 기능은 없다.

* 바이트
1 바이트로 숫자 하나를 표현할 수 있다. 16진수 2자리를 표현할수 있는 것이 1 바이트 (0x00 ~ 0xFF)

이제 unpack을 이용해 좀더 정확하게 데이터를 출력해보겠다.

H -> 2바이트를 묶어서 하나로 만들어준다.
! -> network stream 데이터를 읽어들일때는 !를 붙여준다.
 붙이는 이유 네트워크에서 돌아다니는 데이터랑 컴퓨터에서 다루는 데이터랑 다르다.
 그래서 ! 느낌표를 붙여서 네트워크 데이터라라는것을 알려줘야한다.

이제는 조금 구분 할 수 있게 됬다.


(UDP 헤더 패킷 분석 코드)


-> 목적지 주소가 60000 포트인 경우에만 출력한다. (내가 60000번 포트로 패킷을 전송할거기 때문에
       내가 보내는 패킷의 정보가 궁금한 것.)


(UDP 헤더 분석)



지금까지 Hello라는 데이터를 UDP로 보낼때의 패킷 내용들을 분석해 보았다.

윈도우 소켓으로 볼수있는 것은 L3 까지 볼 수 있다.

- Layer 4 ( Transport Layer ) 의 프로토콜(UDP, TCP)
- L4에서는 데이터가 어디서 어떻게 전달되는지 해당 계층에서는 상관이 없다.
- 에러 정정(UDP에는 없다.), 흐름제어(UDP에는 없다.), 이런 내용만 포함하고 있다.

- L4에서는 관련된 정보만을 포함한다.
-> UDP의 checksum에서는 오류가 났는지 안났는지만 판별 오류났으면 버린다. 그 외의 행동은 하지 않는다. 그래서 에러정정의 기능이 없다고 말한다.


* UDP인지, TCP인지 어떻게 판별할까?
: 더 하위계층에서 그 내용을 가지고 있다. -> IP 패킷

우리가 잘라냈던 IP헤더를 보면 UDP인지 TCP인지 확인할 수 있다.
socket 생성시 PROTOCOL 부분을  IPPROTO_UDP 를 IPPROTO_IP로 바꾸었다.



(socket 타입 변경)


UDP = User Datagram Protocol

IP 헤더 ( Internet Protocol Header )
-> L3 ( Network Layer (네트워크 계층) )
-> IP는 해당 계층의 대표적인 프로토콜이다.
-> 데이터를 송신지에서 수신지로 향하게 하는 데이터의 전달과 밀접한 관련이 있다.
-> 주요목적은 전송경로 설정 등이 있다.
-> 경로에대한 담당은 라우터가 하는것이다. 즉 IP헤더에는 IP주소만 적혀있고 라우터가 IP주소를 보고 경로를 설정한다.
-> 사이즈는 기본 20바이트이다. (추가로 옵션이 있긴하다.)
현재 우리가 보는 것은 IPv4의 IP헤더 이다. IPv6는 또 조금 다르다.

Layer2, Layer1의 내용들은 현재 윈도우즈 환경에서는 지원하지 않는다.
윈도우즈 소켓은 Layer3 까지 밖에 지원이 안된다.

이제 IP헤더를 분석해 본다.

(list를 이용해 출력하는 코드)



(IP 헤더 출력 모습)



출력한 IP 헤더
['0x45', '0x0', '0x0', '0x21', '0x35', '0xd3', '0x0', '0x0',
'0x80', '0x11', '0x7c', '0x14', '0xc0', '0xa8', '0x3', '0xa5',
'0xc0', '0xa8', '0x3', '0xef']

ip 헤더 분석
총 20바이트로 되어있다. 

첫번째 바이트 숫자 하나가 2개의 값을 의미한다.
   0x45  -> 4랑 5로 읽을 수 있다.
1. Version -> 맨 앞 4 = IPv4
2. Header length -> 그 뒤 숫자 5 = 헤더의 길이 : 4를 곱해준다. 5x4 = 20 바이트  헤더의 길이다.
3. Service  -> 현대 IPv4에서는 사용하지 않는다. 거의 항상 0으로 초기화된 값이 들어간다.  : 0x0'
4. Total length (전체길이) : 그다음 숫자 2바이트 '0x0', '0x21' = 0x021  = 33바이트
    ( Ip헤더 20바이트, udp패킷 13바이트 )
5. Identification (식별자) : 그다음 숫자 2바이트 '0x35', '0xd3'
6. Flag ->  '0x0'
7. Fragment OFFSET ->  '0x0'
* IP패킷은 여러개로 분할 될 수도있다. 그래서 5,6,7 정보가 필요하다.
    자세한 내용은 다음에 확인하겠다.
8. TTL (Time to live) -> '0x80'  = 128.  ( 윈도우즈에서 만들어진 패킷은 기본적으로 128로 나간다.)
 TTL은 네트워크를 방황하는 패킷들을 예방하기 위해서 있다.
 TTL은 라우터를 한 Hop이라고 지날수 있는 Hop의 수이다.
9. Protocol 타입 -> '0x11' = 17 :  (udp :17번) (tcp:6번) (ICMP: 1번)
10. Header checksum -> '0x7c', '0x14'  checksum은 각 헤더마다 들어있다.
11. 출발지 IP (4글자) : '0xc0', '0xa8', '0x3', '0xa5'  -> 192  168  3  165  
12. 도착지 IP (4글자) : '0xc0', '0xa8', '0x3', '0xef


-> 전송에 관련된 내용들을 가지고 있다.
1,1,2,2,1,1,1,1,2,4,4 개씩 unpack하면 된다. 위 데이터를 끊는 개수이다.



(IP 헤더 내용을 쪼개어 출력하는 코드)



(IP 헤더 분석)


IP 헤더에 무슨 내용들이 있는지
어떤 역할을 하는지
확인하였다.

또, UDP 패킷도 함께 분석하였다.

-> 나중에 이걸 이용해 패킷 스니퍼를 만들것이다.
(비슷한 원리로 만들것이므로 기억해둬야한다.)













+ Recent posts