Beaglebone Black은 Python을 사용하여 Ubuntu 16.04를 실행하는 노트북에 원시 UDP 패킷을 보낼 수 없습니다.

Beaglebone Black은 Python을 사용하여 Ubuntu 16.04를 실행하는 노트북에 원시 UDP 패킷을 보낼 수 없습니다.

알려진 MAC 주소와 IPv4 주소가 있는 시스템에 이더넷을 통해 원시 UDP 패킷을 생성하는 Python 3.6 스크립트를 만들었습니다. 이 스크립트는 이더넷을 통해 Ubuntu 16.04를 실행하는 노트북에 직접 연결된 Beaglebone Black(BBB)에서 실행됩니다. 스크립트는 Ubuntu 시스템에서도 실행됩니다(src 및 dst 주소는 분명히 변경됩니다). 또한 직렬 연결을 통해 BBB 터미널에 액세스합니다. BBB는 노트북에 성공적으로 ping을 보낼 수 있으며 그 반대의 경우도 마찬가지입니다. 노트북이 Python 스크립트를 실행하면 패킷이 Wireshark에 의해 전송된 것으로 나타나고 이더넷 포트 표시등이 깜박인 다음 tcpdumpBBB에서 실행 중인 인스턴스가 패킷이 전송되었음을 확인합니다. 그러나 BBB에서 스크립트를 실행할 때 tcpdumpBBB의 인스턴스에는 패킷이 전송되었다고 표시되지만 이더넷 포트 표시등이 켜지지 않고 랩탑이 패킷을 수신하지 않습니다. 두 시스템 부팅 시 를 실행하면 ifconfig이더넷 인터페이스에 IP 주소가 없으므로 임의의 주소로 설정해야 합니다. (이 작업을 수행하기 전에도 패킷은 반대 방향이 아닌 랩탑의 BBB로 전송됩니다.) .

노트북의 MAC 주소는 AX:XX:XX:XX:XX:XA이고 IP는 192.168.1.XA입니다. BBB의 MAC 주소는 BX:XX:XX:XX:XX:XB이며 IP는 입니다. 192.168.1입니다. XB 저는 모든 것에 포트 1235를 사용합니다.

ifconfig노트북에서 호출하면 다음이 제공됩니다.

enp0s31f6 Link encap:Ethernet  HWaddr AX:XX:XX:XX:XX:XA  
          inet addr:192.168.1.XA  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::56ee:75ff:fece:4227/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:537 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2912 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:154829 (154.8 KB)  TX bytes:516547 (516.5 KB)
          Interrupt:16 Memory:f2200000-f2220000 

BBB를 호출하면 ifconfig다음이 제공됩니다.

eth0      Link encap:Ethernet  HWaddr BX:XX:XX:XX:XX:XB                        
          inet addr:192.168.1.XB  Bcast:192.168.1.255  Mask:255.255.255.0      
          inet6 addr: fe80::6a3:16ff:feba:676a%132688/64 Scope:Link             
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1                    
          RX packets:2124 errors:0 dropped:0 overruns:0 frame:0                 
          TX packets:669 errors:0 dropped:0 overruns:0 carrier:0                
          collisions:0 txqueuelen:1000                                          
          RX bytes:402654 (393.2 KiB)  TX bytes:173920 (169.8 KiB)              
          Interrupt:174  

스크립트가 노트북에서 실행되면 BBB는 tcpdump -n udp -vv -X다음과 같습니다.

04:47:15.179497 IP (tos 0x0, ttl 64, id 52223, offset 0, flags [DF], proto UDP (17), length 33)                                                                 
    192.168.1.XA.1235 > 192.168.1.XB.1235: [no cksum] UDP, length 5           
        0x0000:  4500 0021 cbff 4000 4011 ea79 c0a8 017f  E..!..@[email protected]....      
        0x0010:  c0a8 0183 04d3 04d3 000d 0000 0003 020f  ................      
        0x0020:  0f00 0000 0000 0000 0000 0000 0000       .............. 

스크립트가 BBB에서 실행되면 랩탑은 이를 수신하지 않지만 tcpdump -n udp -vv -XBBB의 디스플레이는 전송됩니다.

04:51:31.613740 IP (tos 0x0, ttl 64, id 34794, offset 0, flags [DF], proto UDP (17), length 33)
    192.168.1.XB.1235 > 192.168.1.XA.1235: [no cksum] UDP, length 5
        0x0000:  4500 0021 87ea 4000 4011 2e8f c0a8 0183  E..!..@.@.......
        0x0010:  c0a8 017f 04d3 04d3 000d 0000 0003 020f  ................
        0x0020:  0f                                       .

랩톱 및 BBB에서 실행되는 python3.6 스크립트는 다음과 같습니다.

import socket
import time
import struct
import random

#the following lists are specified as [src, dst]
#The order of the elements of these two element lists are reversed for the BBB
MAC = ["AX XX XX XX XX XA", "BX XX XX XX XX XB"]
IP = ["192.168.1.XA", "192.168.1.XB"]
port = [1235, 1235]
address = (IP[1], port[1])

#iface = 'eth0' for the BBB, 'enp0s31f6' for Laptop running Ubuntu 16.04
iface = 'enp0s31f6'


def shex(str):
    result = hex(int(str))
    return result[2:].zfill(2)


def ipToHex(ip):
    a = ip.split('.')
    return '{:02X} {:02X} {:02X} {:02X}'.format(*map(int, a))


def checksum(hdr):
    hdr = "".join(hdr.split())
    hdr = " ".join(hdr[i:i + 2] for i in range(0, len(hdr), 2)).split()
    hdr = list(map(lambda x: int(x, 16), hdr))
    hdr = struct.pack("%dB" % len(hdr), *hdr)

    cksum = 0
    for i in range(0, len(hdr), 2):
        word = hdr[i] + (hdr[i + 1] << 8)
        temp = cksum + word
        cksum = (temp & 0xFFFF) + (temp >> 16)
    res = ~cksum & 0xFFFF
    return '{:04X}'.format(((res << 8) & 0xFF00) | ((res >> 8) & 0x00FF))


class EthernetPacket:
    def __init__(self, mac, payload):
        self.srcMAC = mac[0]
        self.dstMAC = mac[1]
        self.type = '{:04X}'.format(0x0800)
        self.payload = payload

    def send(self, sock):
        sock.send(bytes.fromhex(self.srcMAC + self.dstMAC + self.type + self.payload.construct()))
        time.sleep(0.005)


class IPv4Packet:
    def __init__(self, ip, payload):
        self.srcIP = ipToHex(ip[0])
        self.dstIP = ipToHex(ip[1])
        self.ver = "45 00"
        self.id = '{:04X}'.format(0xFFFF & random.randrange(0, 65536)) + " 40 00 40 11"
        self.length = payload.length + 20
        self.payload = payload
        hdr = self.ver + '{:04X}'.format(self.length) + self.id + "0000" + self.srcIP + self.dstIP
        self.checksum = checksum(hdr)

    def construct(self):
        return self.ver + '{:04X}'.format(
        self.length) + self.id + self.checksum + self.srcIP + self.dstIP + self.payload.construct()


class UDPPacket:
    def __init__(self, port, payload):
        self.srcPort = '{:04X}'.format(port[0])
        self.dstPort = '{:04X}'.format(port[1])
        self.checksum = "0000"
        self.length = len(bytes.fromhex(payload)) + 8
        self.payload = payload

    def construct(self):
        return self.srcPort + self.dstPort + '{:04X}'.format(self.length) + self.checksum + self.payload


def main():
    sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW)
    sock.bind((iface, 1235))

    msg = 0

    cmd = input("Enter Command: ")
    task = cmd.split()

    if not task:
        task = ['null']

    while task[0] != 'exit' and task[0] != 'quit' and task[0] != 'close':
        if task[0] == 'light':
            param1, param2 = shex('00') + ' ', shex('00')
        if len(task) > 1:
            param1 = shex(task[1]) + ' '
        if len(task) > 2:
            param2 = shex(task[2])
        msg = '00 03 02 ' + param1 + param2

        u = UDPPacket(port, msg)
        i = IPv4Packet(IP, u)
        e = EthernetPacket(MAC, i)
        e.send(sock)

        cmd = input("Enter Command: ")
        task = cmd.split()

    sock.close()


if __name__ == "__main__":
    main()

도움을 주시면 감사하겠습니다.

관련 정보