반응형

Python으로 WOL 매직패킷 전송하기

사실 별거 없다... 파이썬 socket통신을 이용하면 될 뿐이기에...

 

1. WOL 패킷 생성코드

import socket, struct

def WOL(macAddr):
    sep = macAddr[2]
    macAddr = macAddr.replace(sep,'')
        
    data = b'FFFFFFFFFFFF' + (macAddr * 16).encode()
    send_data = b''
    
    for i in range(0, len(data), 2):
        send_data += struct.pack('B', int(data[i: i + 2], 16))
    
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    sock.sendto(send_data, ('192.168.35.255',9))
    
WOL('11:22:33:44:55:66')

코드 설명

 > sep = macAddr[2]
 > macAddr = macAddr.replace(sep,'')

 : MAC주소에서 ':' 을 제거합니다.

 

 > data = b'FFFFFFFFFFFF' + (macAddr * 16).encode()
 > send_data = b''

 : data는 WOL 패킷에 전송할 데이터이며, send_data는 실제 전송을 위해서 인코딩된 값이 들어갑니다.

 

 > for i in range(0, len(data), 2):
 >     send_data += struct.pack('B', int(data[i: i + 2], 16))

 : struct.pack(format, value) 함수는 value에 해당하는 값을 원하는 포맷으로 반환합니다.

 : 'B'는 unsigned char형태를 의미합니다. 와이어샤크에서 봤었듯이 전송할 데이터가 FF FF FF 와 같이 2byte 단위 데이터이기 때문에 2byte씩 끊어서 unsigned char형태로 변환해주는 작업을 해주었습니다.

 : 포맷형식을 변환하여 사용도 가능하지만, 예를들어 unsigned int를 사용할 경우 8byte의 반환값을 갖기 때문에 range(0, len(data), 8)로 설정해줘야하며, 이 경우 전체 데이터의 길이가 8로 나누어 떯어지지 않으면 별도의 처리를 해야하는 문제가 있습니다.

 

 > sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

 : socket을 정의합니다. 전송할 WOL패킷은, UDP를 사용하기 때문에 SOCK_DGRAM을 사용합니다.

 

> sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

 : socket의 옵션을 설정합니다. 망내에 Broadcasting 시킬 예정이기에 위와같이 설정해야합니다.

   (아래와같이 망주소를 알 경우 안써도 되는거 같습니다.)

 

 > sock.sendto(send_data, ('192.168.35.255',9))

 : 변환된 데이터를 원하는 망(192.168.35.255)에 9번 포트로 전송합니다.

 

전송결과

와이어 샤크 화면

위에 보이

는것처럼, 전송결과 WOL프로토콜로 인식되는 패킷을 송신하는 것을 볼 수 있었습니다.

패킷의 전송내용도 기존에 어플을 이용해서 보냈던것과 거의 큰 차이가 없습니다.

 

차이는 ID, Checksum, 그리고 flags에서 보이는데, ID는 패킷마다 독립적으로 부여되는 값이기에 다른것이 정상이며, Checksum 역시 패킷의 값에 의존하기 때문에 달라질 수 있습니다. (기능적 문제 X)

 

Flags에서 차이가 있었는데, 확인하보니 Don't Fragment에 대한 부분이 채크가 안된것을 볼 수 있었습니다.

 

하지만, 전송하는 데이터의 크기가 144byte기 때문에 정상적인 망에서 해당 패킷이 Fragment(단편화)가 될 일이 없음으로 전혀 문제가 없습니다.

 

이상입니다~

 

끝 ㅎㅎ

 

궁금한것 댓글로 주세요~

반응형
반응형

와이어샤크 + WOL + python

실제 구현에 관련된 코드는 2부에 있습니다.

1부에서는 와이어샤크로 WOL패킷을 확인하고 간단한 이론을 보겠습니다.

 

WOL

WOL은 전원이 종료된 컴퓨터의 랜카드에 특별한 패킷을 송신함으로써 PC를 켜주는 기능을 의미합니다.

WOL을 수행하기 위해서는 기본적으로 PC의 랜카드가 컴퓨터 종료 후에도 WOL 패킷(매직패킷)을 수신할 수 있는 상태여야합니다.(이부분은 여기서 다루지 않겠습니다.)

 

Wireshark

와이어샤크는 네트워크 패킷을 분석하는 가장 대중적인 툴입니다.

간편하게 현재 랜카드가 송신/수신한 모든 패킷들을 확인 할 수 있으며, 해당 패킷의 정보를 쉽게 확인할 수 있도록 간편한 인터페이스를 제공합니다.

 

WOL 패킷확인

Wake On Lan 어플

 

 

 WOL 패킷 확인을 위해서 해당 패킷을 전송하는 어플 [Wake On Lan]을 사용했습니다.

 

 

 

 

왼쪽에 보이는 것처럼 [wol test]라고 [11:22:33:44:55:66]이라는 맥주소를 갖고있는 컴퓨터에 WOL 패킷을 전송하도록 해주었습니다.

 

이때 와이어샤크로 감자하는 PC와 해당 스마트폰은 동일한 네트워크망에 접속되어있어야합니다.(공유기 종류 무관)

 

 

 

 

 

 

 

 

 

 

 

 

 

와이어 샤크 패킷수신화면

WOL이 사용하는 udp 9번 포트를 필터링한 결과 3개의 패킷이 전송된 것을 볼 수 있었습니다.

(맥주소는 굳이 가려봤습니다.)

 

한번에 어플이 3개의 패킷을 송신하는 것을 볼 수 있었습니다.

 

 

패킷정보(총 144byte)

와이어샤크 수신 패킷

와이어샤크 화면 하단에 표시된 내용을 순서대로 말씀드리겠습니다.

 

 

Ethernet 계층 (MAC프레임)

Ethernet (Data Link) Layer
이미지 출처 : 정보통신기술용어해설

  • DA(Dst Mac Address) = 'ff ff ff ff ff ff'
  • SA(Src Mac Address) = '50 77 05 -- -- --' 
  • Ethertype(Ethernet Protocol Type) = '08 00' (IPv4)

참고) 이더넷 타입표

  • Data = Layer3 이상부분

 

 

 

Network 계층 (IP Header)

Network Layer
이미지 출처 : 정보통신기술용어해설

  • Verson = '4'
    • IPv4
  • Header Length = '5'
    • Header Length는 위 IP헤더에서 한 줄을 의미합니다.
    • 즉 5x4byte = 20byte로 IP헤더의 최소길이를 의미합니다.
  • Type of Service = '00'
    • 미할당 영역으로 추가기능을 위한 공간입니다.
  •  Total Length = '00 82'
    • 8x16+2 = 130byte
    • 즉, IP Packet = Header(20byte) + Data(110byte) 로 이루어집니다.
  • Identification = '29 22'
    • Packet에 부여되는 식별자(오류제어등에 사용됨)
  • Flags + Fragment offset
    • Flags는 3bit 공간에 각 자리수가 특정의미를 갖음
    • [ Reserved bit | Don't Fragment | More Fragments | 
    • 40 = 010 = Don't Fragment
    • offset은 단편화가 된 경우 패킷의 순서를 확인하는 용도로 사용됨
  • TTL(Time to Live) = '40'
    • 패킷이 통과할 수 있는 노드의 수를 의미합니다.
    • 노드를 통과할 때 마다 1씩 감소하며 0이되면 전송실패와 함께, ICMP 메시지를 전송합니다.
  • Protocol type = '11'
    • 프로토콜 맵팽은 아래와 같습니다.
    • ICMP = 1 | IGMP = 2 | TCP = 6 | EGP = 8 | UDP = 17 | OSPF = 89 등...
    • 11 = 10진수로 17(즉, UDP를 의미)
  • Header Checksum = '48 69'
    • Checksum은 오류검출용 코드입니다.
  • Src IP Addr = 'c9 a8 23 90' (192.168.35.144)
  • Dst IP Addr = 'c0 a8 23 ff' (192.168.35.255)
    • WOL 기능은 목적지 주소를 망주소로 전송합니다.

 

 

 

Transport (UDP Datagram)

Transport Layer (UDP Datagram)
이미지 출처 : 정보통신기술용어해설

  • Src Port = 'eb e5' (60389)
  • Dst Port = '00 09' (9)
    • WOL은 수신 Port로 7 또는 9를 사용합니다.
  • Length = '00 6e' (110)
    • 위어서 언급한 것처럼, IP Packet에서 Data영역이었던 UDP부분이 110Byte임을 볼 수 있습니다.
  • Checksum = 'ad 79'
    • 수신측 오류확인을 위해 사용합니다.

 

 

 

Application (WOL Data)

Application Layer (WOL Data)

WOL은 특별한 데이터를 넘겨줍니다.

UDP Data로 들어온 WOL 정보

'FF FF FF FF FF FF' Broadcast MAC 주소와 목적지의 MAC 주소의 조합으로 이루어집니다.

 

위와 같이 하나의 'Broadcast' + 16개(또는 20개)의 '목적지 MAC 주소'로 이루어집니다.

 

 

 

 

끝?

 

다음 게시물은 위의 패킷을 생성하는 파이썬 코드를 보겠습니다. 이상입니다.

반응형

+ Recent posts