반응형

WOL 기능에서 사용되는 매직패킷을 전송하는 프로그램

python + pyqt

 

0. 개발환경

  • 맥북 OSX
  • PyCharm (Python 3.7x) + pyqt

1. GUI

 

먼저 대략적인 앱 디자인을 구성합니다.

저는 위와같이 대충 만들었습니다.

정확한 크기는 코딩단계에서 조절해줍니다.

 

[QT 디자이너]를 사용하지 않을 예정이기 때문에 대충 목표디자인을 파워포인트로 잡았습니다.

 

 

 

 

2. Coding

udp통신이고 기존에 파이썬으로 WOL패킷전송을 수행하는 코드를 작성해둔 적이 있었기 때문에 해당코드를 그대로 이용했습니다.

 

2019/05/14 - [이론/네트워크] - [네트워크 패킷] Python으로 WOL패킷 송신하기(1/2)

2019/05/14 - [이론/네트워크] - [네트워크 패킷] Python으로 WOL패킷 송신하기(2/2)

 

 

import sys
import socket, struct, time
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QPixmap, QIcon
from PyQt5.QtCore import Qt

class LayoutWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        wg = WidgetSet()
        self.setCentralWidget(wg)
        self.statusBar().showMessage('Youngq.tistory.com')

        self.setWindowTitle('WOL Program')
        self.setWindowIcon(QIcon('web.png'))
        self.setGeometry(500, 500, 350, 180)
        self.show()

class WidgetSet(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        # Line 1 : Wol 이미지 + msg 영역
        hbox0 = QHBoxLayout()
        hbox0.setAlignment(Qt.AlignVCenter)

        pixmap = QPixmap('wol_mini.png')
        pixmap = pixmap.scaledToWidth(35)
        lbl_img = QLabel()
        lbl_img.setPixmap(pixmap)
        hbox0.addWidget(lbl_img)
        hbox0.addStretch(200)

        msg = QLabel()
        msg.setFixedSize(200,25)
        msg.setText("Ready")
        msg.setAlignment(Qt.AlignRight)
        self.err = msg
        hbox0.addWidget(msg)

        # Line 2 : 대역폭입력 + 콤보박스
        hbox1 = QHBoxLayout()
        hbox1.setAlignment(Qt.AlignVCenter)

        qle1 = QLineEdit(self)
        qle1.setFixedSize(170, 25)
        qle1.setPlaceholderText("목적지 IP주소 또는 망주소 입력")
        self.ip = qle1
        hbox1.addWidget(qle1)
        hbox1.addStretch(20)

        cIP = QLabel()
        cIP.setFixedSize(110, 30)
        currentIP = self.ipaddr()
        cIP.setText("IP : "+currentIP)
        hbox1.addWidget(cIP)

        # Line 3 : 맥주소 입력 + 전송버튼
        hbox2 = QHBoxLayout()
        hbox2.setAlignment(Qt.AlignHorizontal_Mask)
        qle2 = QLineEdit(self)
        qle2.setFixedSize(170, 25)
        qle2.setPlaceholderText("MAC 주소 입력")
        self.mac = qle2
        hbox2.addWidget(qle2)
        hbox2.addStretch(20)

        btn = QPushButton(self)
        btn.setText('Send')
        btn.setFixedSize(70, 30)
        self.sendBtn = btn
        btn.clicked.connect(self.sending) # EventH

        hbox2.addWidget(btn)
        # Stacking : 레이아웃 배치
        vbox = QVBoxLayout()
        vbox.addLayout(hbox0)
        vbox.addLayout(hbox1)
        vbox.addLayout(hbox2)
        self.setLayout(vbox)

    def sending(self):
        try:
            WOL(self.mac.text(), self.ip.text())
            self.err.setText("신호 전송완료")
        except:
            self.err.setText("잘못된 입력이 존재합니다.")

    def ipaddr(self):
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80))
        return s.getsockname()[0]

def WOL(macAddr, network):
    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)
    for i in range(3):
        sock.sendto(send_data, (network, 9))
        time.sleep(0.05)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = LayoutWindow()
    sys.exit(app.exec_())

 

특별한 알고리즘이 필요없는 단순 프로그램이지만, GUI 구성까지 포함해서 100줄 조금 넘어가는 코드로... 역시 파이썬입니다...

 

해당 코드는 다음 링크에서 복사 가능합니다.

 

https://github.com/yekyu94/WOL_python/blob/master/wol.py

 

yekyu94/WOL_python

python WOL GUI Coding. Contribute to yekyu94/WOL_python development by creating an account on GitHub.

github.com

 

Pyqt를 통해서 제작한 코드이기 때문에 pyqt가 설치되어있지 않는 경우 애러가 발생합니다.

 

 

 

 

3. Testing

 

 

실행화면
와이어샤크로 확인

 

위와같이 전송이 완료되면 입력한 IP주소와 MAC주소를 타겟으로한 WOL패킷이 3개 전송되는 것을 볼 수 있습니다.

 

이렇게 만든 프로그램을 pyinstaller같은 라이브러리를 이용하여 쉽게 exe파일등으로 변환이 가능합니다.

 

해당부분은 넘어가겠습니다.

반응형
반응형

0. 정의

  • 그래프(G)는 정점(Vertex)와 간선(Edge)로 이루어집니다.   * G = (V, E)
  • 인접(Adjacent) : 간선(Edge)으로 연결된 두 정접(Vertex)
  • 완전그래프(Complete Graph) : 간선(Edge)의 개수가 최대인 그래프
  • 경로(Path) : 경로의 길이는 경로사이의 간선(Edge)의 수
  • Directed Graph : 방향성이 있는 간선(Edge)을 갖는 그래프
  • Undirected Graph : 방향성이 없는 간선(Edge)을 갖는 그래프

 

그래프는 아래와 같이 표현합니다.

그래프 예제

 

표를 이용한 그래프 표현

 

 

1. Graph Traversal

그래프의 탐색방법은 크게 두가지로 나눠집니다.

 

  • Depth First Search(DFS) : 깊이 우선 탐색
  • Breadth First Search(BFS) : 너비 우선 탐색

두 개념은 그래프와 트리와 같이 Vertex와 Edge로 이루어진 자료구조에서 사용되는 탐색방법입니다.

 

두개의 차이는 아래를 참고하면 쉽게 이해할 수 있습니다.

 

출처 : http://blog.hackerearth.com/wp-content/uploads/2015/05/dfsbfs_animation_final.gif

 

DFS는 순환호출 형태로 많이 구현하며 BFS는 Quere를 이용하여 쉽게 구현할 수 있습니다.

 

void DFS(Vertex* V)
{
	Edge* E = NULL;
    printf("%d ", V->Data);
    
    V->Visited = Visited;
    
    E = V->AdjacencyList;
    
    while(E != NULL){
    	if( E->Target != NULL && E->Target->Visited == NotVisited )
        	DFS( E-> Target );
        
        E = E->Nest;
    }
}
       

전체 알고리즘자료는 깃헙에 올리고있습니다. => https://github.com/yekyu94

 

yekyu94 - Overview

네트워크 프로그래밍 / 텐서플로우 / 보안 / 고양이. yekyu94 has 15 repositories available. Follow their code on GitHub.

github.com

 

 

반응형
반응형

1. DNS Query Message

DNS는 UDP 53번 포트를 사용합니다.

 

DNS Packet

Google.com에 접속했을 때 위와같은 DNS query와 DNS response가 전송되는 것을 볼 수 있습니다.

 

먼저 DNS Query Message를 확인해보면 아래와 같은 것을 볼 수 있습니다.

 

DNS Query Message

위의 붉게 표시한 부분이 DNS Header에 해당하는 부분입니다.

 

DNS message Header는 기본적으로 [트랜잭션 ID, flag, Question count, Answer count, Name server count, Additional Recode count]를 갖고 있습니다.

 

현재 해당 Packet의 DNS Message 는 아래와 같습니다.

 

Transaction ID = 0b 8e

Flags = 0100

Questions = 1

Answer = 0

Authority RRs = 0

Additional RRS = 0

Queries = www.google.com

 

 

2. Query Flag

트랜잭션 ID는 매 Query에 대한 식별 ID이며, Flags 0x0100은 아래와 같이 맵핑됩니다.

QR

Opcode

AA

TC

RD

RA

000

rCode

0

0000

0

0

1

0

000

0000

 

  • OR 0 : 이 메시지가 Query 라는 의미
  • Opcode 0000 : 표준 질의 또는 표준 질의에 대한 응답
  • AA 0 : 네임서버 권한이 인정 X
  • TC 0 : 응답메시지가 512 바이트 이하
  • RD 1 : 응답 형태가 Recursive인지 Iterative인지 정해주는 것으로 여기서 1은 Recursive 응답을 요구한다는 의미
  • RA 0 : 네임서버가 Recursive 질의가 가능한지 나타내며
  • rCode : 0 = No Error (1 = Format Error, 2 = ServFail, 3 = DNS존재 X)

 

3. DNS Response Message

DNS Response Message

 

마찬가지로 해당 패킷의 Response Message는 아래와 같은 내용을 갖고있습니다.

Transaction ID = 0b 8e

Flags = 81 80

Questions = 1

Answer = 6

Authority RRs = 4

Additional RRS = 8

Queries = www.google.com

Answers = 

www.google.com addr 108.177.97.104

www.google.com addr 108.177.97.105

www.google.com addr 108.177.97.147

www.google.com addr 108.177.97.99

www.google.com addr 108.177.97.103

www.google.com addr 108.177.97.106

Authoritative Nameservers =

google.com ns ns4.Google.com

google.com ns ns1.Google.com

google.com ns ns2.Google.com

google.com ns ns3.Google.com

Additional records =

ns1.google.com addr 216.239.32.10

ns2.google.com addr 216.239.34.10

ns3.google.com addr 216.239.36.10

ns4.google.com addr 216.239.38.10

ns1.google.com addr 2001:4860:4802:32::a

ns2.google.com addr 2001:4860:4802:34::a

ns3.google.com addr 2001:4860:4802:36::a

ns4.google.com addr 2001:4860:4802:38::a

 

 

4. Response Flag

이 Packet의 Transaction ID는 Query의 Transaction ID와 동일하며, Flags는 아래와 같이 매핑됩니다.

QR

Opcode

AA

TC

RD

RA

000

rCode

1

0000

0

0

1

1

000

0000

 

  • OR 1 : 이 메시지가 response 라는 의미
  • Opcode 0000 : 표준 질의 또는 표준 질의에 대한 응답
  • AA 0 : 네임서버 권한이 인정 X
  • TC 0 : 응답메시지가 512 바이트 이하
  • RD 1 : 응답 형태가 Recursive인지 Iterative인지 정해주는 것으로 여기서 1은 Recursive 응답을 요구한다는 의미
  • RA 1 : 네임서버가 Recursive 질의가 가능한지 나타내며
  • rCode : 0 = No Error (1 = Format Error, 2 = ServFail, 3 = DNS존재 X) 

이 응답 메시지로부터 client는 www.google.com이라는 사이트의 address와 Google.com의 네임서버를 얻어올 수 있습니다.

반응형

+ Recent posts