Score:0

อุปกรณ์แตะสองตัวไม่สามารถสื่อสารผ่านบริดจ์ได้

ธง cn

ฉันต้องการแลกเปลี่ยน Ethernet Packet ระหว่างอุปกรณ์แตะสองเครื่อง (สำหรับการนำโปรโตคอล TCP/IP stack ไปใช้ในโหมดผู้ใช้)

ปัญหาที่ฉันพบคือ tap1 และ tap2 สามารถรับแพ็กเก็ตออกอากาศผ่านบริดจ์เท่านั้น แต่ไม่สามารถรับแพ็กเก็ตแบบจุดต่อจุดได้!

ตัวอย่างเช่น เมื่อฉันส่งแพ็กเก็ตจาก tap1 ไปยัง tap2 tcmpdump สามารถจับแพ็กเก็ตบน tap1 ได้ แต่ tap2 ไม่สามารถรับแพ็กเก็ตได้ อย่างไรก็ตาม เมื่อฉันตั้งค่าที่อยู่ปลายทางเป็น "ff:ff:ff:ff:ff:ff" หรืออื่นๆ ที่อยู่ mac ที่ไม่รู้จัก (นี่จะเป็นการส่งสัญญาณทริกเกอร์) tap2 จะได้รับแพ็กเก็ต

การกำหนดค่าของฉัน:

  1. สร้างอุปกรณ์แตะสองเครื่อง
ip tuntap เพิ่มโหมด tap tun1
ip tuntap เพิ่มโหมด tap tun2
# กำหนดที่อยู่ IP สำหรับการนำโปรโตคอล arp ไปใช้
ip addr เพิ่ม 172.19.16.1 dev tun1
ip addr เพิ่ม 172.19.16.2 dev tun2

ลิงค์ ip ตั้งค่า tun1 ขึ้น
ลิงค์ ip ตั้งค่า tun2 ขึ้น
  1. สร้างสะพาน
brctl บวกbr br0
brctl addif br0 tun1
brctl addif br0 tun2

ลิงค์ ip ตั้งค่า br0 ขึ้น

ต่อไปนี้คือสถานะของบริดจ์และอินเตอร์เฟสการแตะ: แม็ค:

พอร์ตไม่มี mac addr อยู่ในเครื่องหรือไม่ ตัวจับเวลาอายุ
  2 46:44:6e:55:9b:c5 ใช่ 0.00
  2 46:44:6e:55:9b:c5 ใช่ 0.00
  1 f2:6b:68:c9:60:6b ใช่ 0.00
  1 f2:6b:68:c9:60:6b ใช่ 0.00

สถานะ:

br0
 รหัสบริดจ์ 8000.46446e559bc5
 กำหนดรูท 8000.46446e559bc5
 รูทพอร์ต 0 เส้นทางต้นทุน 0
 อายุสูงสุด 20.00 น. อายุสะพานสูงสุด 20.00 น
 สวัสดีเวลา 2.00 สะพานสวัสดีเวลา 2.00 น
 เดินหน้าล่าช้า 15.00 สะพาน เดินหน้าล่าช้า 15.00 น
 อายุการใช้งาน 300.00
 สวัสดี จับเวลา 0.00 tcn จับเวลา 0.00
 ตัวจับเวลาการเปลี่ยนแปลงโทโพโลยี 0.00 gc ตัวจับเวลา 89.77
 ธง


อุโมงค์1 (1)
 พอร์ต id 8001 สถานะการส่งต่อ
 เส้นทาง root 8000.46446e559bc5 ที่กำหนดราคา 100
 บริดจ์ที่กำหนด 8000.46446e559bc5 ตัวจับเวลาอายุข้อความ 0.00
 พอร์ตที่กำหนด 8001 ตัวตั้งเวลาหน่วงไปข้างหน้า 0.00
 ค่าใช้จ่ายที่กำหนด 0 ตัวจับเวลา 0.00
 ธง

ทูนทู (2)
 พอร์ต id 8002 สถานะการส่งต่อ
 เส้นทาง root 8000.46446e559bc5 ที่กำหนดราคา 100
 บริดจ์ที่กำหนด 8000.46446e559bc5 ตัวจับเวลาอายุข้อความ 0.00
 พอร์ตที่กำหนด 8002 ตัวตั้งเวลาหน่วงไปข้างหน้า 0.00
 ค่าใช้จ่ายที่กำหนด 0 ตัวจับเวลา 0.00
 ธง

ต่อไปนี้เป็นรหัสทดสอบของฉัน:

นำเข้าfcntl
นำเข้าระบบปฏิบัติการ
นำเข้า if_tun
ctypes นำเข้า

โครงสร้างการนำเข้า
จากการนำเข้า scapy.all *


จาก if_tun นำเข้า IfReq, TUNSETIFF, IFF_TUN


def register_tun (ชื่อ: str):
    fd = os.open("/dev/net/tun",os.O_RDWR)
    ถ้า fd < 0:
        กลับ fd

    r = IfReq()

    ctypes.memset(ctypes.byref(r), 0, ctypes.sizeof(r))
    r.ifr_ifru.ifru_flags = 0x0002 | 0x1000
    r.ifr_ifrn.ifrn_name = name.encode("utf-8")
    
    fcntl.ioctl(fd, TUNSETIFF,r)
    กลับ fd


ถ้า __name__ == "__main__":
    ชื่อ = อินพุต ("ชื่ออุปกรณ์อินพุต")
    fd = register_tun (ชื่อ)
    ถ้า fd < 0:
        พิมพ์ ("ข้อผิดพลาด")
    ถ้าชื่อ == "tun2":
        ในขณะที่ทรู:
            buf = os.read(fd,1024)
            พิมพ์ (f "รับข้อมูล {len (buf)}")
            อีเธอร์(ดิบ(บัฟ)).แสดง()
    mac1 = "f2:6b:68:c9:60:6b"
    mac2 = "46:44:6e:55:9b:c5"
    ในขณะที่ทรู:
        ประเภท = อินพุต ()
        a = อีเธอร์(dst=mac2,src=mac1)/ARP(pdst="172.19.16.1",psrc="172.19.16.2")
        การแสดง()
        พิมพ์ ("เขียน:")
        พิมพ์ (os.write (fd, ดิบ (a)))

หมายเหตุ:

  1. แม้ว่าชื่ออุปกรณ์จะเรียกว่า tun แต่เป็นประเภท tap
  2. ฉันรันโค้ดทดสอบสองโค้ดพร้อมกัน โค้ดหนึ่งเชื่อมต่อ tun1 และอีกโค้ดหนึ่งเชื่อมต่อ tun2 ดังนั้นอุปกรณ์สองเครื่องจึงมีสถานะ LOWWER_UP
A.B avatar
cl flag
A.B
ดูคำถาม/คำตอบของฉันนี้: https://serverfault.com/questions/994721/ping-does-not-work-on-tap-interfaces-with-bridge/996479#996479 (อย่างที่คุณทราบดีว่าคุณต้องการแอป userland ที่น่าสนใจเพียงบางส่วนเท่านั้น)
Miracle avatar
cn flag
@A.B ขอบคุณสำหรับความคิดเห็นของคุณ ฉันรู้ว่าฉันต้องจัดการโปรโตคอล arp ด้วยตัวเอง แต่ตอนนี้ฉันไม่สามารถส่ง Ethernet Packet จาก tap1 ไปยัง tap2 ได้ ดังนั้นฉันจึงไม่สามารถใช้โปรโตคอล arp ด้วยตัวเองได้
Miracle avatar
cn flag
@A.B ตัวเลือกใดดีกว่าระหว่าง tap,tun(point-to-point),veth(using raw socket) ถ้าฉันต้องการใช้ tcp/ip stack ในโหมดผู้ใช้ ตามความคิดของฉัน ฉันต้องการเพียงวิธีเขียน Ether Packet ไปยังอินเทอร์เฟซเครือข่ายโดยตรง การใช้ไดรเวอร์เครือข่ายนั้นซับซ้อนและยากมากอย่างเห็นได้ชัด การใช้ tun ยังต้องแก้ไขนโยบายเส้นทางท้องถิ่น แล้ว veth pair (พื้นที่เครือข่ายที่แตกต่างกันโดยใช้ซ็อกเก็ตดิบ) ล่ะ? ฉันไม่รู้ว่าฉันควรลองวิธีไหน
Miracle avatar
cn flag
@A.B แรงจูงใจของฉันคือการเรียนรู้ tcp/ip อย่างลึกซึ้ง ขอบคุณมากหลังจากตั้งค่าแล้วใช้งานได้ แต่ฉันไม่ค่อยเข้าใจว่าทำไมต้องเปลี่ยนที่อยู่ mac ของ tun1 f2:6b:68:c9:60:6b->f2:6b:68:c9:60:6c และ tun2 46:44:6e:55:9b :c5->46:44:6e:55:9b:c6 . ที่อยู่ mac ทั้งสองถูกจัดสรรโดยระบบปฏิบัติการ ฉันจำเป็นต้องเปลี่ยนที่อยู่ปลายทางของ Ether Packet ด้วยหรือไม่ หากไม่มี สิ่งนี้จะทริกเกอร์ออกอากาศ ตามที่ฉันเข้าใจ บริดจ์ทำหน้าที่เป็นสวิตช์บทบาทและสามารถกำหนดเส้นทาง Ether Packet ที่สอดคล้องกับที่อยู่ Mac ปลายทาง อย่างไรก็ตาม ในสถานการณ์นี้ มันสามารถแพร่ภาพแพ็กเก็ตเท่านั้น
Score:0
ธง cn

บางทีฉันอาจมีเหตุผล

Tap/Tun เชื่อมโยงสแต็กเครือข่ายและโปรแกรมผู้ใช้โปรแกรมผู้ใช้สามารถรับข้อมูลใด ๆ ซึ่งเขียนเพื่อแตะการ์ดโดยสแต็กเครือข่าย.

สมมติว่าเรามีโปรแกรม 1 ฟัง tap1 (mac1) และโปรแกรม 2 ฟัง เพื่อ tap2 (mac2)

หากโปรแกรม 1 เขียน Ether Packet(src=mac1,dst=mac2) ไปยัง tap1 สแต็กเครือข่ายจะได้รับแพ็กเก็ตโปรแกรม 2 สามารถรับแพ็กเก็ตได้ก็ต่อเมื่อเครือข่ายสแต็คเขียนแพ็กเก็ตไปยัง tap2

เห็นได้ชัดว่าเป็นไปไม่ได้! Mac-Frame ที่ไม่มีฟังก์ชันการกำหนดเส้นทาง นอกจากนี้ แพ็กเก็ตยังเป็นของโฮสต์ปัจจุบัน

อย่างไรก็ตาม เมื่อเราเขียนแพ็กเก็ตออกอากาศ สแต็กเครือข่ายจะส่งต่อแพ็กเก็ตไปยังการ์ดเครือข่ายทุกตัว ยกเว้น tap1

ข้างต้นเป็นเพียงความเข้าใจตื้นของฉัน ไม่รู้ว่าถูกหรือเปล่า

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา