Skip to content

실습 목표#

  • 랜선을 이용하여 노트북과 라즈베리파이를 연결하고, 고정 IP를 할당하여 연결을 확인한다.
  • ARP, ICMP, UDP 통신을 해보고 Wireshark를 통해 패킷을 분석한다.


실습 환경 설정#


라즈베리파이 고정 IP 설정#

랜선을 라즈베리파이와 노트북의 이더넷 포트에 직접 연결 후, vscode에서 ssh로 라즈베리파이를 연결한다. 라즈베리파이 터미널에 다음 명령어들을 입력하여 고정 IP를 설정한다.


라즈베리파이·콘솔
sudo nmcli con add type ethernet ifname eth0 con-name lab-static \
    ip4 192.168.10.2/24
sudo nmcli con up lab-static
ip addr show eth0

관찰 포인트

ip addr 출력의 eth0 항목에 ip4 192.168.10.2/24가 보이면 성공이다.


노트북 고정 IP 설정#

다음과 같이 윈도우 설정에서 이더넷 어댑터의 IP를 수동으로 지정한다.
설정 → 네트워크 및 인터넷 → 이더넷 → IP 할당 → 설정 편집

노트북 고정 IP 설정


이더넷 연결 확인#

노트북과 라즈베리파이 각각에서 ping 명령어로 연결 상태를 확인한다. 응답이 오면 연결 성공, 타임 아웃이 발생하면 연결 실패이다.

노트북·명령 프롬프트
ping 192.168.10.2
라즈베리파이·터미널
ping 192.168.10.1


실습 1. ARP 캡처#


실습 진행#

ARP(Address Resolution Protocol)는 상대 IP의 MAC 주소를 알아내는 프로토콜이다. 라즈베리파이의 IP 주소만 알고 MAC 주소를 모르기 때문에 ARP를 통해 MAC 주소를 알아낸다. WireShark에서 라즈베리파이와 연결된 이더넷 어댑터 더블 클릭 → 필터 'arp'로 설정하여 캡처를 시작한다. ARP 캡처


캐시 삭제 후, ping 명령어를 실행한다.

노트북(관리자 권한 명령 프롬프트)
arp -d *
ping 192.168.10.2

관찰 포인트

이 때 요청과 응답이 한 쌍으로 잡히는지, 각각의 Dst MAC이 무엇인지 확인한다.


상대방의 MAC Address를 모르기 때문에 Broadcasting을 통해 요청한다. 한 번 알아낸 MAC Address는 ARP Cache에 저장하고 이후 통신에서는 ARP를 사용하지 않고 Cache를 참조한다. ARP 캡처 Destination을 보면 Broadcast라고 되어있는 것을 확인할 수 있다.


ARP Request 분석#

다음 표를 참고하여 ARP Request를 분석한다.

ff ff ff ff ff ff 11 22 33 44 55 66 08 06 00 01
08 00 06 04 00 01 11 22 33 44 55 66 c0 a8 0a 01
00 00 00 00 00 00 c0 a8 0a 02

오프셋 바이트 필드 의미
0~5 ff ff ff ff ff ff Dst MAC Broadcast
6~11 11 22 33 44 55 66 Src MAC 노트북 MAC Address
12 ~ 13 08 06 Type ARP
14~15 00 01 Hardware Type 이더넷
16~17 08 00 Protocol Type IPv4
18 06 Hardware Size MAC Address Size
19 04 Protocol Size IP Address Size
20 ~ 21 00 01 Opcode Request
22 ~ 27 11 22 33 44 55 66 Sender MAC 노트북 MAC Address
28 ~ 31 c0 a8 0a 01 Sender IP 192.168.10.1
32 ~ 37 00 00 00 00 00 00 Target MAC Broadcast
38 ~ 41 c0 a8 0a 02 Target IP 192.168.10.2

ARP Response 분석#

다음 표를 참고하여 ARP Response를 분석한다.

11 22 33 44 55 66 aa bb cc dd ee ff 08 06 00 01
08 00 06 04 00 02 aa bb cc dd ee ff c0 a8 0a 02
11 22 33 44 55 66 c0 a8 0a 01 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00

오프셋 바이트 필드 의미
0 ~ 5 11 22 33 44 55 66 Dst MAC 노트북 MAC Address
6 ~ 11 aa bb cc dd ee ff Src MAC 라즈베리파이 MAC Address
12 ~ 13 08 06 Type ARP
14 ~ 15 00 01 Hardware Type 이더넷
16 ~1 7 08 00 Protocol Type IPv4
18 06 Hardware Size MAC Address Size
19 04 Protocol Size IP Address Size
20 ~ 21 00 02 Opcode Response
22 ~ 27 aa bb cc dd ee ff Sender MAC 라즈베리파이 MAC Address
28 ~ 31 c0 a8 0a 01 Sender IP 192.168.10.2
32 ~ 37 11 22 33 44 55 66 Target MAC 노트북 MAC Address
38 ~ 41 c0 a8 0a 02 Target IP 192.168.10.1
42 ~ 59 00 00 ⋯ 00 00 Padding 최소 60 Bytes를 채우는 0

ARP 패킷 구조#

ARP 요청 프레임은 42bytes로, 이더넷 헤더 14 bytes 뒤에 ARP 메시지 28bytes가 붙는다. 이미지


실습 2. ICMP 캡처#


실습 진행#

WireShark에서 필터를 ‘arp || icmp’로 설정한다. 이 때 한 번의 ping에 request와 reply가 한 쌍씩 총 8번의 ICMP 통신이 이루어진다.


ICMP Request 분석#

다음 표를 참고하여 ICMP Request를 분석한다.

aa bb cc dd ee ff 11 22 33 44 55 66 08 00 45 00
00 3c 97 97 00 00 80 01 00 00 c0 a8 0a 01 c0 a8
0a 02

오프셋 바이트 필드 의미
0~5 aa bb cc dd ee ff Dst MAC 라즈베리파이 MAC Address
6~11 11 22 33 44 55 66 Src MAC 노트북 MAC Address
12 ~ 13 08 00 Type IPv4
14 45 Version / IHL IPv4 · Header 20 Bytes
15 00 DSCP / ECN 우선순위 없음
16~17 00 3c Total Length 60 Bytes (IP 20 + ICMP 8 + Data 32)
18 ~ 19 97 97 Identification Fragment 식별 번호
20 ~ 21 00 00 Flags / Offset Fragment 없음
22 80 TTL 128 · Windows 기본값
23 01 Protocol ICMP
24 ~ 25 00 00 Header Checksum NIC가 계산 · 0으로 표시
26 ~ 29 c0 a8 0a 01 Src IP 192.168.10.1
30 ~ 33 c0 a8 0a 02 Dst IP 192.168.10.2


08 00 4b 87 00 01 01 d4 61 62 63 64 65 66 67 68
69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 61
62 63 64 65 66 67 68 69
오프셋 바이트 필드 의미
34 08 Type Echo Request
35 00 Code 0
36 ~ 37 4b 87 Checksum 오류 검출
38 ~ 39 00 01 Identifier ping 프로세스 구분
40 ~ 41 01 d4 Sequence Number 468번째 요청
42 ~ 73 61 62 63 ⋯ 68 69 Data 알파벳 32 Bytes


ICMP Reply 분석#

다음 표를 참고하여 ICMP Reply를 분석한다.

11 22 33 44 55 66 aa bb cc dd ee ff 08 00 45 00
00 3c c4 95 00 00 40 01 d0 d7 c0 a8 0a 02 c0 a8
0a 01

오프셋 바이트 필드 의미
0 ~ 5 11 22 33 44 55 66 Dst MAC 노트북 MAC Address
6 ~ 11 aa bb cc dd ee ff Src MAC 라즈베리파이 MAC Address
12 ~ 13 08 00 Type IPv4
14 45 Version / IHL IPv4 · Header 20 Bytes
15 00 DSCP / ECN 우선순위 없음
16 ~ 17 00 3c Total Length 60 Bytes (IP 20 + ICMP 8 + Data 32)
18 ~ 19 c4 95 Identification Fragment 식별 번호
20 ~ 21 00 00 Flags / Offset Fragment 없음
22 40 TTL 64 · Linux 기본값
23 01 Protocol ICMP
24 ~ 25 d0 d7 Header Checksum 오류 검출
26 ~ 29 c0 a8 0a 02 Src IP 192.168.10.2
30 ~ 33 c0 a8 0a 01 Dst IP 192.168.10.1


00 00 53 87 00 01 01 d4 61 62 63 64 65 66 67 68
69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 61
62 63 64 65 66 67 68 69
오프셋 바이트 필드 의미
34 00 Type Echo Reply
35 00 Code 0
36 ~ 37 53 87 Checksum Type이 바뀌어 다시 계산
38 ~ 39 00 01 Identifier Request와 동일
40 ~ 41 01 d4 Sequence Number 468번째 요청
42 ~ 73 61 62 63 ⋯ 68 69 Data 알파벳 32 Bytes


ICMP 패킷 구조#

ICMP는 IP 위에서 동작하므로 이더넷과 IP 헤더를 거쳐 전달된다. 캡처된 프레임은 총 74bytes이다. ICMP 캡처


실습 3. UDP 예제 코드 실행#


실습 진행#

라즈베리파이와 노트북에서 각각 아래와 같이 build한다. 라즈베리파이에서 'udp_server'를 먼저 실행하고, 노트북에서 'udp_client'를 실행한다.

라즈베리파이 (터미널)
make
./udp_server
노트북 (WSL)
make
./udp_client

WireShark에서 필터를 'udp.port==9999’로 설정하여 결과를 분석한다. UDP 예제 코드 실행


UDP 패킷 분석#

다음 표를 참고하여 UDP 패킷을 분석한다.

aa bb cc dd ee ff 11 22 33 44 55 66 08 00 45 00
00 31 73 bb 40 00 40 11 e1 ac c0 a8 0a 01 c0 a8
0a 02

오프셋 바이트 필드 의미
0 ~ 5 aa bb cc dd ee ff Dst MAC 라즈베리파이 MAC Address
6 ~ 11 11 22 33 44 55 66 Src MAC 노트북 MAC Address
12 ~ 13 08 00 Type IPv4
14 45 Version / IHL IPv4 · Header 20 Bytes
15 00 DSCP / ECN 우선순위 없음
16 ~ 17 00 31 Total Length 49 Bytes (IP 20 + ICMP 8 + Data 21)
18 ~ 19 73 bb Identification Fragment 식별 번호
20 ~ 21 40 00 Flags / Offset Fragment 없음 · DF
22 40 TTL 64 · Linux 기본값
23 11 Protocol UDP
24 ~ 25 e1 ac Header Checksum 오류 검출
26 ~ 29 c0 a8 0a 01 Src IP 192.168.10.1
30 ~ 33 c0 a8 0a 01 Dst IP 192.168.10.2


9b a1 27 0f 00 1d 52 2c 48 65 6c 6c 6f 20 55 44
50 20 66 72 6f 6d 20 6c 61 70 74 6f 70
오프셋 바이트 필드 의미
34 ~ 35 9b a1 Src Port 39841 · OS 임시 할당
36 ~ 37 27 0f Dst Port 9999
38 ~ 39 00 1d Length 29 Bytes (Header 8 + Data 21)
40 ~ 41 52 2c Checksum 오류 검출
42 ~ 62 48 65 6c 6c 6f ⋯ 6f 70 Data Hello UDP from laptop


과제 1. 보내는 데이터 변경#


노트북 udp_client_blank.cpp에서 보내는 데이터를 변경한다. 실습3과 동일한 방식으로 build 후, 라즈베리파이에서 udp_server를 먼저 실행하고, 노트북에서 udp_client_blank를 실행한다.

udp_client_blank.cpp
const char* msg = "Hello UDP from laptop";
노트북·WSL
g++ -std=c++17 -O2 udp_client_blank.cpp -o udp_client_blank
./udp_client_blank


과제 2. 서버가 응답 보내기#


이번에는 라즈베리파이 udp_server_blank.cpp에서 보내는 데이터를 변경한다. 실습3과 동일하게 build 후, 라즈베리파이에서 udp_server_blank를 먼저 실행하고 노트북에서 udp_client를 실행한다.

udp_server.cpp · recvfrom 다음 줄에 추가
const char* reply = "ACK from Pi";
sendto(sock, reply, strlen(reply), 0, (sockaddr*)&cli, clilen);
라즈베리파이·터미널
g++ -std=c++17 -O2 udp_server.cpp -o udp_server
./udp_server