magic packet 릴레이.python

본문 바로가기
사이트 내 전체검색

로그인
회원가입
IT Note

magic packet 릴레이.python
1

View 18  | 작성일2025.01.07 17:13

본문

외부에서 공유기 너머 pc 를 wol 으로 깨우려 할 때 pc 가 꺼진 시간이 길어지면

공유기에서 arp 정보 유실로 제대로 깨워지지 않는 문제가 있다고 합니다.

공유기에서 arp 바인딩 기능을 지원하면 그렇게 하면 되고

그렇지 않다면 간단히 라즈베리파이 같은 상시 켜둘 수 있는 저전력 기기로 패킷을 릴레이 시킬 수 있는 서비스를 띄워두라고 해서 작성해 봤습니다.


import socket, fcntl, struct



LISTEN_PORT = 10009

INTERFACES = ["eth0", "wlan0"]



def get_broadcast_address(interface):

    try:

        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

        return socket.inet_ntoa(fcntl.ioctl(

              s.fileno(),

              0x8919,

              struct.pack('256s', interface[:15].encode('utf-8'))

        )[20:24])

    except Exception as e:

        print(f'Error getting broadcast address for {interface}: {e}')

        return None


def broadcast_magic_packet(mac_address):

    """주어진 MAC 주소로 매직 패킷 생성 및 브로드캐스트"""

    mac_address = mac_address.replace(":", "").replace("-", "")

    if len(mac_address) != 12:

        print(f"Invalid MAC address: {mac_address}")

        return


    # 매직 패킷 생성

    magic_packet = bytes.fromhex("FF" * 6 + mac_address * 16)


    for interface in INTERFACES:

        broadcast_addr = get_broadcast_address(interface)

        if broadcast_addr is None:

            print(f"Skipping interface {interface} due to missing broadcast address")

            continue


        try:

            # 브로드캐스트 전송

            with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:

                s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

                s.setsockopt(socket.SOL_SOCKET, 25, interface.encode('utf-8') + b'\0')

                s.sendto(magic_packet, (broadcast_addr, 9))

            print(f"Broadcasted magic packet for MAC: {mac_address} on {interface}")

        except Exception as e:

            print(f"Error broadcasting on {interface}: {e}")



def listen_for_magic_packets():

    """UDP 포트에서 매직 패킷 수신 대기"""

    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:

        s.bind(("0.0.0.0", LISTEN_PORT))  # 모든 IP로부터 수신 대기

        print(f"Listening for magic packets on UDP port {LISTEN_PORT}...")


        while True:

            data, addr = s.recvfrom(1024)  # 패킷 데이터와 발신 주소

            print(f"Received packet from {addr}")


            # MAC 주소 추출 (데이터 형식에 따라 조정 필요)

            mac_address = extract_mac_address(data)

            if mac_address:

                print(f"Extracted MAC address: {mac_address}")

                broadcast_magic_packet(mac_address)


def extract_mac_address(data):

    """패킷 데이터에서 MAC 주소 추출"""

    # 매직 패킷의 형식 검증 (6바이트 FF + 16번 MAC)

    if len(data) >= 102 and data[:6] == b'\xff' * 6:

        mac = data[6:12]

        return ':'.join(f"{byte:02x}" for byte in mac)

    print("Invalid magic packet format")

    return None


if __name__ == "__main__":

    listen_for_magic_packets()


공유기 포워딩 설정을 통해서 10009 로 포워딩 받은 후 물려 있는 nic 마다 브로드캐스팅 뿌려주는 파이썬 코드입니다.


댓글목록

하아… 이거 뭔짓을 해도 안돼서 이제 WOL은 안되나보다 했는데 공유기에서 그런 뒷사정이 있었군요…
좋은정보 감사합니다

IT Tip&Tech 목록

게시물 검색

접속자집계

오늘
424
어제
1,750
최대
6,399
전체
1,012,870
Copyright © LittleCandle All rights reserved.
문의메일 : littlecandle99@gmail.com
모바일 버전으로 보기