เซิร์ฟเวอร์ DHCP+Mysql ใน Python

เซิร์ฟเวอร์ DHCP+Mysql ใน Python

วัตถุประสงค์ของโครงการนี้คือ:

  • เรียนรู้เกี่ยวกับ DHCP บนเครือข่าย IPv4
  • การเรียนรู้ Python (มากกว่าตั้งแต่เริ่มต้นเล็กน้อย 😉)
  • การเปลี่ยนเซิร์ฟเวอร์ DB2DHCP (ส้อมของฉัน) ดั้งเดิม ที่นี่ซึ่งการประกอบสำหรับระบบปฏิบัติการใหม่นั้นยากขึ้นเรื่อยๆ และฉันไม่ชอบที่มันเป็นเลขฐานสองที่ไม่มีทาง “เปลี่ยนแปลงได้ในตอนนี้”
  • รับเซิร์ฟเวอร์ DHCP ที่ใช้งานได้พร้อมความสามารถในการเลือกที่อยู่ IP ของผู้สมัครสมาชิกโดยใช้ mac ของผู้สมัครสมาชิกหรือสลับการรวม mac + พอร์ต (ตัวเลือก 82)
  • เขียนจักรยานอีกคัน (โอ้! นี่คือกิจกรรมโปรดของฉัน)
  • รับความคิดเห็นเกี่ยวกับความถนัดชมรมของคุณบน Habrahabr (หรือดีกว่านั้นคือคำเชิญ) 😉

ผลลัพธ์: มันใช้งานได้ 😉 ทดสอบบน FreeBSD และ Ubuntu OS ตามทฤษฎีแล้วโค้ดสามารถถูกขอให้ทำงานภายใต้ระบบปฏิบัติการใดก็ได้เพราะว่า ดูเหมือนจะไม่มีการผูกมัดเฉพาะในโค้ด
อย่างระมัดระวัง! ยังมีอีกมากที่จะมา

ลิงค์คลังสำหรับมือสมัครเล่น "สัมผัสมีชีวิต".

กระบวนการติดตั้งกำหนดค่าและใช้งานผลของ "การศึกษาฮาร์ดแวร์" นั้นต่ำกว่ามากและมีทฤษฎีเล็กน้อยเกี่ยวกับโปรโตคอล DHCP สำหรับตัวฉันเอง และสำหรับประวัติศาสตร์😉

ทฤษฎีเล็กน้อย

DHCP คืออะไร

นี่คือโปรโตคอลเครือข่ายที่อนุญาตให้อุปกรณ์ค้นหาที่อยู่ IP (และพารามิเตอร์อื่นๆ เช่น เกตเวย์, DNS ฯลฯ) จากเซิร์ฟเวอร์ DHCP แพ็กเก็ตจะถูกแลกเปลี่ยนโดยใช้โปรโตคอล UDP หลักการทำงานของอุปกรณ์โดยทั่วไปเมื่อขอพารามิเตอร์เครือข่ายมีดังนี้:

  1. อุปกรณ์ (ไคลเอนต์) ส่งคำขอออกอากาศ UDP (DHCPDISCOVER) ทั่วทั้งเครือข่ายพร้อมคำขอ “มีคนให้ที่อยู่ IP แก่ฉัน” ยิ่งไปกว่านั้น โดยปกติ (แต่ไม่เสมอไป) คำขอจะเกิดขึ้นจากพอร์ต 68 (ต้นทาง) และปลายทางคือพอร์ต 67 (ปลายทาง) อุปกรณ์บางตัวยังส่งแพ็กเก็ตจากพอร์ต 67 ด้วย ที่อยู่ MAC ของอุปกรณ์ไคลเอ็นต์จะรวมอยู่ในแพ็กเก็ต DHCPDISCOVER
  2. เซิร์ฟเวอร์ DHCP ทั้งหมดที่อยู่ในเครือข่าย (และอาจมีหลายเซิร์ฟเวอร์) สร้างข้อเสนอ DHCPOFFER พร้อมการตั้งค่าเครือข่ายสำหรับอุปกรณ์ที่ส่ง DHCPDISCOVER และยังออกอากาศผ่านเครือข่ายอีกด้วย การระบุผู้ที่แพ็คเก็ตนี้มีไว้สำหรับจะขึ้นอยู่กับที่อยู่ MAC ของไคลเอนต์ที่ให้ไว้ก่อนหน้าในคำขอ DHCPDISCOVER
  3. ลูกค้ายอมรับแพ็กเก็ตพร้อมข้อเสนอสำหรับการตั้งค่าเครือข่าย เลือกอันที่น่าสนใจที่สุด (เกณฑ์อาจแตกต่างกัน เช่น เวลาในการจัดส่งแพ็กเก็ต จำนวนเส้นทางกลาง) และทำการ "คำขออย่างเป็นทางการ" DHCPREQUEST พร้อมการตั้งค่าเครือข่าย จากเซิร์ฟเวอร์ DHCP ที่ชอบ ในกรณีนี้ แพ็กเก็ตจะไปที่เซิร์ฟเวอร์ DHCP ที่ระบุ
  4. เซิร์ฟเวอร์ที่ได้รับ DHCPREQUEST จะส่งแพ็กเก็ตรูปแบบ DHCPACK ซึ่งจะแสดงการตั้งค่าเครือข่ายสำหรับไคลเอ็นต์นี้อีกครั้ง

เซิร์ฟเวอร์ DHCP+Mysql ใน Python

นอกจากนี้ยังมีแพ็กเก็ต DHCPINFORM ที่มาจากไคลเอนต์ และมีวัตถุประสงค์เพื่อแจ้งให้เซิร์ฟเวอร์ DHCP ทราบว่า “ไคลเอนต์ยังมีชีวิตอยู่” และกำลังใช้การตั้งค่าเครือข่ายที่ออกให้ ในการใช้งานเซิร์ฟเวอร์นี้ แพ็กเก็ตเหล่านี้จะถูกละเว้น

รูปแบบแพ็คเกจ

โดยทั่วไป เฟรมแพ็กเก็ตอีเธอร์เน็ตจะมีลักษณะดังนี้:

เซิร์ฟเวอร์ DHCP+Mysql ใน Python

ในกรณีของเรา เราจะพิจารณาเฉพาะข้อมูลโดยตรงจากเนื้อหาของแพ็กเก็ต UDP โดยไม่มีส่วนหัวโปรโตคอลเลเยอร์ OSI กล่าวคือ โครงสร้าง DHCP:

DHCPค้นพบ

ดังนั้น กระบวนการรับที่อยู่ IP สำหรับอุปกรณ์เริ่มต้นด้วยไคลเอ็นต์ DHCP ที่ส่งคำขอออกอากาศจากพอร์ต 68 ถึง 255.255.255.255:67 ในแพ็คเกจนี้ ไคลเอนต์จะรวมที่อยู่ MAC รวมถึงสิ่งที่ต้องการรับจากเซิร์ฟเวอร์ DHCP โครงสร้างบรรจุภัณฑ์อธิบายไว้ในตารางด้านล่าง

ตารางโครงสร้างแพ็คเก็ต DHCPDISCOVER

ตำแหน่งในแพ็คเกจ
ชื่อค่า
ตัวอย่าง
ความคิด
ไบต์
การอธิบาย

1
คำขอบูต
1
แม่มด
1
ประเภทข้อความ 1 - คำขอจากไคลเอนต์ไปยังเซิร์ฟเวอร์ 2 - การตอบสนองจากเซิร์ฟเวอร์ไปยังไคลเอนต์

2
ประเภทฮาร์ดแวร์
1
แม่มด
1
ประเภทของที่อยู่ฮาร์ดแวร์ในโปรโตคอลนี้ 1 - MAC

3
ความยาวที่อยู่ฮาร์ดแวร์
6
แม่มด
1
ความยาวที่อยู่ MAC ของอุปกรณ์

4
Hops
1
แม่มด
1
จำนวนเส้นทางระหว่างทาง

5
รหัสธุรกรรม
23:cf:de:1d
แม่มด
4
ตัวระบุธุรกรรมที่ไม่ซ้ำ สร้างโดยไคลเอนต์เมื่อเริ่มต้นการดำเนินการร้องขอ

7
ครั้งที่สองผ่านไป
0
แม่มด
4
เวลาเป็นวินาทีนับจากเริ่มต้นกระบวนการรับที่อยู่

9
ธงบูต
0
แม่มด
2
การตั้งค่าสถานะบางอย่างที่สามารถตั้งค่าเพื่อระบุพารามิเตอร์โปรโตคอล

11
ที่อยู่ IP ของลูกค้า
0.0.0.0
เส้น
4
ที่อยู่ IP ของลูกค้า (ถ้ามี)

15
ที่อยู่ IP ของลูกค้าของคุณ
0.0.0.0
เส้น
4
ที่อยู่ IP ที่เซิร์ฟเวอร์นำเสนอ (ถ้ามี)

19
ที่อยู่ IP ของเซิร์ฟเวอร์ถัดไป
0.0.0.0
เส้น
4
ที่อยู่ IP ของเซิร์ฟเวอร์ (ถ้าทราบ)

23
ที่อยู่ IP ของตัวแทนรีเลย์
172.16.114.41
เส้น
4
ที่อยู่ IP ของตัวแทนรีเลย์ (เช่น สวิตช์)

27
ที่อยู่ MAC ของไคลเอ็นต์
14:d6:4d:a7:c9:55
แม่มด
6
ที่อยู่ MAC ของผู้ส่งแพ็คเก็ต (ไคลเอนต์)

31
การขยายที่อยู่ฮาร์ดแวร์ไคลเอ็นต์
 
แม่มด
10
สำรองที่นั่ง. มักจะเต็มไปด้วยเลขศูนย์

41
ชื่อโฮสต์ของเซิร์ฟเวอร์
 
เส้น
64
ชื่อเซิร์ฟเวอร์ DHCP ปกติไม่ถ่ายทอด.

105
ชื่อไฟล์บูต
 
เส้น
128
ชื่อไฟล์บนเซิร์ฟเวอร์ที่ใช้โดยสเตชั่นไร้ดิสก์เมื่อทำการบูท

235
คุกกี้เมจิก
63: 82: 53: 63
แม่มด
4
หมายเลข “เวทย์มนตร์” ตามที่ระบุ ได้แก่ คุณสามารถระบุได้ว่าแพ็กเก็ตนี้เป็นของโปรโตคอล DHCP

ตัวเลือก DHCP จะไปลำดับไหนก็ได้

236
หมายเลขตัวเลือก
53
ธันวาคม
1
ตัวเลือก 53 ซึ่งระบุประเภทแพ็กเก็ต DHCP

1 - DHCPDISCOVER
3 - DHCPREQUEST
2 - ดีเอชซีโปเฟอร์
5 - ดีเอชซีแพ็ค
8 - DHCPINFORM

 
ความยาวตัวเลือก
1
ธันวาคม
1

 
ค่าตัวเลือก
1
ธันวาคม
1

 
หมายเลขตัวเลือก
50
ธันวาคม
1
ลูกค้าต้องการรับที่อยู่ IP ใด

 
ความยาวตัวเลือก
4
ธันวาคม
1

 
ค่าตัวเลือก
172.16.134.61
เส้น
4

 
หมายเลขตัวเลือก
55
 
1
พารามิเตอร์เครือข่ายที่ร้องขอโดยไคลเอนต์ องค์ประกอบอาจแตกต่างกันไป

01 — เน็ตเวิร์กมาสก์
03 - เกตเวย์
06 - DNS
oc — ชื่อโฮสต์
0f - ชื่อโดเมนเครือข่าย
1c - ที่อยู่ของคำขอออกอากาศ (ออกอากาศ)
42 - ชื่อเซิร์ฟเวอร์ TFTP
79 - เส้นทางคงที่แบบไม่มีคลาส

 
ความยาวตัวเลือก
8
 
1

 
ค่าตัวเลือก
01:03:06:0c:0f:1c:42:79
 
8

 
หมายเลขตัวเลือก
82
ธันวาคม
 
ตัวเลือก 82 ซึ่งส่งที่อยู่ MAC ของอุปกรณ์ทวนสัญญาณและค่าเพิ่มเติมบางส่วน

ส่วนใหญ่แล้วนี่คือพอร์ตของสวิตช์ที่ไคลเอ็นต์ DHCP ปลายทางทำงาน ตัวเลือกนี้มีพารามิเตอร์เพิ่มเติม ไบต์แรกคือหมายเลขของ "ตัวเลือกย่อย" ไบต์ที่สองคือความยาวจากนั้นตามด้วยค่า

ในกรณีนี้ ในตัวเลือก 82 ตัวเลือกย่อยจะซ้อนกัน:
Agent Circuit ID = 00:04:00:01:00:04 โดยที่สองไบต์สุดท้ายคือพอร์ตไคลเอ็นต์ DHCP ที่มีการร้องขอ

Agent Remote ID = 00:06:c8:be:19:93:11:48 - ที่อยู่ MAC ของอุปกรณ์ทวนสัญญาณ DHCP

 
ความยาวตัวเลือก
18
ธันวาคม
 

 
ค่าตัวเลือก
01:06
00:04:00:01:00:04
02:08
00:06:c8:be:19:93:11:48
แม่มด
 

 
สิ้นสุดแพ็คเกจ
255
ธันวาคม
1
255 เป็นสัญลักษณ์ของการสิ้นสุดแพ็กเก็ต

ดีเอชซีพอฟเฟอร์

ทันทีที่เซิร์ฟเวอร์ได้รับแพ็กเก็ต DHCPDISCOVER และหากเห็นว่าสามารถเสนอบางสิ่งให้กับลูกค้าจากแพ็กเก็ตที่ร้องขอได้ ก็จะสร้างการตอบกลับสำหรับมัน - DHCPDISCOVER คำตอบจะถูกส่งไปที่ท่าเรือ “จากที่มันมา” โดยออกอากาศเพราะว่า ในขณะนี้ ลูกค้ายังไม่มีที่อยู่ IP ดังนั้นจึงสามารถยอมรับแพ็กเก็ตได้ก็ต่อเมื่อมีการส่งโดยการออกอากาศเท่านั้น ลูกค้ารับรู้ว่านี่คือแพ็คเกจสำหรับเขาตามที่อยู่ MAC ของเขาภายในแพ็คเกจ รวมถึงหมายเลขธุรกรรมที่เขาสร้างในเวลาที่สร้างแพ็คเกจแรก

ตารางโครงสร้างแพ็คเก็ต DHCPOFFER

ตำแหน่งในแพ็คเกจ
ชื่อของค่า (ทั่วไป)
ตัวอย่าง
ความคิด
ไบต์
การอธิบาย

1
คำขอบูต
1
แม่มด
1
ประเภทข้อความ 1 - คำขอจากไคลเอนต์ไปยังเซิร์ฟเวอร์ 2 - การตอบสนองจากเซิร์ฟเวอร์ไปยังไคลเอนต์

2
ประเภทฮาร์ดแวร์
1
แม่มด
1
ประเภทของที่อยู่ฮาร์ดแวร์ในโปรโตคอลนี้ 1 - MAC

3
ความยาวที่อยู่ฮาร์ดแวร์
6
แม่มด
1
ความยาวที่อยู่ MAC ของอุปกรณ์

4
Hops
1
แม่มด
1
จำนวนเส้นทางระหว่างทาง

5
รหัสธุรกรรม
23:cf:de:1d
แม่มด
4
ตัวระบุธุรกรรมที่ไม่ซ้ำ สร้างโดยไคลเอนต์เมื่อเริ่มต้นการดำเนินการร้องขอ

7
ครั้งที่สองผ่านไป
0
แม่มด
4
เวลาเป็นวินาทีนับจากเริ่มต้นกระบวนการรับที่อยู่

9
ธงบูต
0
แม่มด
2
การตั้งค่าสถานะบางอย่างที่สามารถตั้งค่าเพื่อระบุพารามิเตอร์โปรโตคอล ในกรณีนี้ 0 หมายถึงประเภทคำขอแบบผู้รับเดียว

11
ที่อยู่ IP ของลูกค้า
0.0.0.0
เส้น
4
ที่อยู่ IP ของลูกค้า (ถ้ามี)

15
ที่อยู่ IP ของลูกค้าของคุณ
172.16.134.61
เส้น
4
ที่อยู่ IP ที่เซิร์ฟเวอร์นำเสนอ (ถ้ามี)

19
ที่อยู่ IP ของเซิร์ฟเวอร์ถัดไป
0.0.0.0
เส้น
4
ที่อยู่ IP ของเซิร์ฟเวอร์ (ถ้าทราบ)

23
ที่อยู่ IP ของตัวแทนรีเลย์
172.16.114.41
เส้น
4
ที่อยู่ IP ของตัวแทนรีเลย์ (เช่น สวิตช์)

27
ที่อยู่ MAC ของไคลเอ็นต์
14:d6:4d:a7:c9:55
แม่มด
6
ที่อยู่ MAC ของผู้ส่งแพ็คเก็ต (ไคลเอนต์)

31
การขยายที่อยู่ฮาร์ดแวร์ไคลเอ็นต์
 
แม่มด
10
สำรองที่นั่ง. มักจะเต็มไปด้วยเลขศูนย์

41
ชื่อโฮสต์ของเซิร์ฟเวอร์
 
เส้น
64
ชื่อเซิร์ฟเวอร์ DHCP ปกติไม่ถ่ายทอด.

105
ชื่อไฟล์บูต
 
เส้น
128
ชื่อไฟล์บนเซิร์ฟเวอร์ที่ใช้โดยสเตชั่นไร้ดิสก์เมื่อทำการบูท

235
คุกกี้เมจิก
63: 82: 53: 63
แม่มด
4
หมายเลข “เวทย์มนตร์” ตามที่ระบุ ได้แก่ คุณสามารถระบุได้ว่าแพ็กเก็ตนี้เป็นของโปรโตคอล DHCP

ตัวเลือก DHCP จะไปลำดับไหนก็ได้

236
หมายเลขตัวเลือก
53
ธันวาคม
1
ตัวเลือก 53 ซึ่งกำหนดประเภทแพ็กเก็ต DHCP 2 - DHCPOFFER

 
ความยาวตัวเลือก
1
ธันวาคม
1

 
ค่าตัวเลือก
2
ธันวาคม
1

 
หมายเลขตัวเลือก
1
ธันวาคม
1
ตัวเลือกในการเสนอเน็ตเวิร์กมาสก์ให้กับไคลเอ็นต์ DHCP

 
ความยาวตัวเลือก
4
ธันวาคม
1

 
ค่าตัวเลือก
255.255.224.0
เส้น
4

 
หมายเลขตัวเลือก
3
ธันวาคม
1
ตัวเลือกในการเสนอเกตเวย์เริ่มต้นให้กับไคลเอ็นต์ DHCP

 
ความยาวตัวเลือก
4
ธันวาคม
1

 
ค่าตัวเลือก
172.16.12.1
เส้น
4

 
หมายเลขตัวเลือก
6
ธันวาคม
1
ตัวเลือกในการเสนอ DHCP ให้กับไคลเอนต์ DNS

 
ความยาวตัวเลือก
4
ธันวาคม
1

 
ค่าตัวเลือก
8.8.8.8
เส้น
4

 
หมายเลขตัวเลือก
51
ธันวาคม
1
อายุการใช้งานของพารามิเตอร์เครือข่ายที่ออกในหน่วยวินาที หลังจากนั้นไคลเอ็นต์ DHCP จะต้องร้องขออีกครั้ง

 
ความยาวตัวเลือก
4
ธันวาคม
1

 
ค่าตัวเลือก
86400
ธันวาคม
4

 
หมายเลขตัวเลือก
82
ธันวาคม
1
ตัวเลือก 82 ทำซ้ำสิ่งที่มาใน DHCPDISCOVER

 
ความยาวตัวเลือก
18
ธันวาคม
1

 
ค่าตัวเลือก
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:เช่น
ธันวาคม
18

 
สิ้นสุดแพ็คเกจ
255
ธันวาคม
1
255 เป็นสัญลักษณ์ของการสิ้นสุดแพ็กเก็ต

DHCPREQUEST

หลังจากที่ไคลเอ็นต์ได้รับ DHCPOFFER แล้ว เขาจะฟอร์มแพ็กเก็ตที่ร้องขอพารามิเตอร์เครือข่าย ไม่ใช่กับเซิร์ฟเวอร์ DHCP ทั้งหมดบนเครือข่าย แต่เฉพาะกับเซิร์ฟเวอร์ใดเซิร์ฟเวอร์หนึ่งเท่านั้น ซึ่ง DHCPOFFER เสนอข้อเสนอที่เขา "ชอบ" มากที่สุด เกณฑ์ "ชอบ" อาจแตกต่างกันและขึ้นอยู่กับการใช้งาน DHCP ของไคลเอ็นต์ ระบุผู้รับคำขอโดยใช้ที่อยู่ MAC ของเซิร์ฟเวอร์ DHCP นอกจากนี้ ไคลเอนต์สามารถส่งแพ็กเก็ต DHCPREQUEST ได้โดยไม่ต้องสร้าง DHCPDISCOVER ก่อน หากได้รับที่อยู่ IP ของเซิร์ฟเวอร์ก่อนหน้านี้

ตารางโครงสร้างแพ็คเก็ต DHCPREQUEST

ตำแหน่งในแพ็คเกจ
ชื่อของค่า (ทั่วไป)
ตัวอย่าง
ความคิด
ไบต์
การอธิบาย

1
คำขอบูต
1
แม่มด
1
ประเภทข้อความ 1 - คำขอจากไคลเอนต์ไปยังเซิร์ฟเวอร์ 2 - การตอบสนองจากเซิร์ฟเวอร์ไปยังไคลเอนต์

2
ประเภทฮาร์ดแวร์
1
แม่มด
1
ประเภทของที่อยู่ฮาร์ดแวร์ในโปรโตคอลนี้ 1 - MAC

3
ความยาวที่อยู่ฮาร์ดแวร์
6
แม่มด
1
ความยาวที่อยู่ MAC ของอุปกรณ์

4
Hops
1
แม่มด
1
จำนวนเส้นทางระหว่างทาง

5
รหัสธุรกรรม
23:cf:de:1d
แม่มด
4
ตัวระบุธุรกรรมที่ไม่ซ้ำ สร้างโดยไคลเอนต์เมื่อเริ่มต้นการดำเนินการร้องขอ

7
ครั้งที่สองผ่านไป
0
แม่มด
4
เวลาเป็นวินาทีนับจากเริ่มต้นกระบวนการรับที่อยู่

9
ธงบูต
8000
แม่มด
2
การตั้งค่าสถานะบางอย่างที่สามารถตั้งค่าเพื่อระบุพารามิเตอร์โปรโตคอล ในกรณีนี้ "ออกอากาศ" จะถูกตั้งค่าไว้

11
ที่อยู่ IP ของลูกค้า
0.0.0.0
เส้น
4
ที่อยู่ IP ของลูกค้า (ถ้ามี)

15
ที่อยู่ IP ของลูกค้าของคุณ
172.16.134.61
เส้น
4
ที่อยู่ IP ที่เซิร์ฟเวอร์นำเสนอ (ถ้ามี)

19
ที่อยู่ IP ของเซิร์ฟเวอร์ถัดไป
0.0.0.0
เส้น
4
ที่อยู่ IP ของเซิร์ฟเวอร์ (ถ้าทราบ)

23
ที่อยู่ IP ของตัวแทนรีเลย์
172.16.114.41
เส้น
4
ที่อยู่ IP ของตัวแทนรีเลย์ (เช่น สวิตช์)

27
ที่อยู่ MAC ของไคลเอ็นต์
14:d6:4d:a7:c9:55
แม่มด
6
ที่อยู่ MAC ของผู้ส่งแพ็คเก็ต (ไคลเอนต์)

31
การขยายที่อยู่ฮาร์ดแวร์ไคลเอ็นต์
 
แม่มด
10
สำรองที่นั่ง. มักจะเต็มไปด้วยเลขศูนย์

41
ชื่อโฮสต์ของเซิร์ฟเวอร์
 
เส้น
64
ชื่อเซิร์ฟเวอร์ DHCP ปกติไม่ถ่ายทอด.

105
ชื่อไฟล์บูต
 
เส้น
128
ชื่อไฟล์บนเซิร์ฟเวอร์ที่ใช้โดยสเตชั่นไร้ดิสก์เมื่อทำการบูท

235
คุกกี้เมจิก
63: 82: 53: 63
แม่มด
4
หมายเลข “เวทย์มนตร์” ตามที่ระบุ ได้แก่ คุณสามารถระบุได้ว่าแพ็กเก็ตนี้เป็นของโปรโตคอล DHCP

ตัวเลือก DHCP จะไปลำดับไหนก็ได้

236
หมายเลขตัวเลือก
53
ธันวาคม
3
ตัวเลือก 53 ซึ่งกำหนดแพ็กเก็ต DHCP ประเภท 3 - DHCPREQUEST

 
ความยาวตัวเลือก
1
ธันวาคม
1

 
ค่าตัวเลือก
3
ธันวาคม
1

 
หมายเลขตัวเลือก
61
ธันวาคม
1
รหัสไคลเอ็นต์: 01 (สำหรับ Ehernet) + ที่อยู่ MAC ของไคลเอ็นต์

 
ความยาวตัวเลือก
7
ธันวาคม
1

 
ค่าตัวเลือก
01:2c:ab:25:ff:72:a6
แม่มด
7

 
หมายเลขตัวเลือก
60
ธันวาคม
 
"ตัวระบุคลาสผู้ขาย" ในกรณีของฉัน รายงานเวอร์ชันไคลเอ็นต์ DHCP บางทีอุปกรณ์อื่นอาจส่งคืนสิ่งที่แตกต่างออกไป ตัวอย่างเช่น Windows รายงาน MSFT 5.0

 
ความยาวตัวเลือก
11
ธันวาคม
 

 
ค่าตัวเลือก
udhcp 0.9.8
เส้น
 

 
หมายเลขตัวเลือก
55
 
1
พารามิเตอร์เครือข่ายที่ร้องขอโดยไคลเอนต์ องค์ประกอบอาจแตกต่างกันไป

01 — เน็ตเวิร์กมาสก์
03 - เกตเวย์
06 - DNS
oc — ชื่อโฮสต์
0f - ชื่อโดเมนเครือข่าย
1c - ที่อยู่ของคำขอออกอากาศ (ออกอากาศ)
42 - ชื่อเซิร์ฟเวอร์ TFTP
79 - เส้นทางคงที่แบบไม่มีคลาส

 
ความยาวตัวเลือก
8
 
1

 
ค่าตัวเลือก
01:03:06:0c:0f:1c:42:79
 
8

 
หมายเลขตัวเลือก
82
ธันวาคม
1
ตัวเลือก 82 ทำซ้ำสิ่งที่มาใน DHCPDISCOVER

 
ความยาวตัวเลือก
18
ธันวาคม
1

 
ค่าตัวเลือก
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:เช่น
ธันวาคม
18

 
สิ้นสุดแพ็คเกจ
255
ธันวาคม
1
255 เป็นสัญลักษณ์ของการสิ้นสุดแพ็กเก็ต

ดีเอชซีแพ็ค

เพื่อเป็นการยืนยันว่า "ใช่ ถูกต้อง นี่คือที่อยู่ IP ของคุณและฉันจะไม่ให้ผู้อื่น" จากเซิร์ฟเวอร์ DHCP ซึ่งเป็นแพ็กเก็ตในรูปแบบ DHCPACK จากเซิร์ฟเวอร์ไปยังไคลเอนต์ที่ให้บริการ มันจะถูกส่งออกอากาศเช่นเดียวกับแพ็กเก็ตอื่นๆ แม้ว่าในโค้ดด้านล่างสำหรับเซิร์ฟเวอร์ DHCP ที่ใช้งานใน Python ในกรณีนี้ ฉันทำซ้ำคำขอออกอากาศใด ๆ โดยการส่งแพ็กเก็ตไปยัง IP ไคลเอนต์เฉพาะ หากทราบอยู่แล้ว นอกจากนี้ เซิร์ฟเวอร์ DHCP ไม่สนใจเลยว่าแพ็กเก็ต DHCPACK เข้าถึงไคลเอนต์แล้วหรือไม่ หากไคลเอนต์ไม่ได้รับ DHCPACK หลังจากนั้นครู่หนึ่งก็จะทำซ้ำ DHCPREQUEST

ตารางโครงสร้างแพ็คเก็ต DHCPACK

ตำแหน่งในแพ็คเกจ
ชื่อของค่า (ทั่วไป)
ตัวอย่าง
ความคิด
ไบต์
การอธิบาย

1
คำขอบูต
2
แม่มด
1
ประเภทข้อความ 1 - คำขอจากไคลเอนต์ไปยังเซิร์ฟเวอร์ 2 - การตอบสนองจากเซิร์ฟเวอร์ไปยังไคลเอนต์

2
ประเภทฮาร์ดแวร์
1
แม่มด
1
ประเภทของที่อยู่ฮาร์ดแวร์ในโปรโตคอลนี้ 1 - MAC

3
ความยาวที่อยู่ฮาร์ดแวร์
6
แม่มด
1
ความยาวที่อยู่ MAC ของอุปกรณ์

4
Hops
1
แม่มด
1
จำนวนเส้นทางระหว่างทาง

5
รหัสธุรกรรม
23:cf:de:1d
แม่มด
4
ตัวระบุธุรกรรมที่ไม่ซ้ำ สร้างโดยไคลเอนต์เมื่อเริ่มต้นการดำเนินการร้องขอ

7
ครั้งที่สองผ่านไป
0
แม่มด
4
เวลาเป็นวินาทีนับจากเริ่มต้นกระบวนการรับที่อยู่

9
ธงบูต
8000
แม่มด
2
การตั้งค่าสถานะบางอย่างที่สามารถตั้งค่าเพื่อระบุพารามิเตอร์โปรโตคอล ในกรณีนี้ "ออกอากาศ" จะถูกตั้งค่าไว้

11
ที่อยู่ IP ของลูกค้า
0.0.0.0
เส้น
4
ที่อยู่ IP ของลูกค้า (ถ้ามี)

15
ที่อยู่ IP ของลูกค้าของคุณ
172.16.134.61
เส้น
4
ที่อยู่ IP ที่เซิร์ฟเวอร์นำเสนอ (ถ้ามี)

19
ที่อยู่ IP ของเซิร์ฟเวอร์ถัดไป
0.0.0.0
เส้น
4
ที่อยู่ IP ของเซิร์ฟเวอร์ (ถ้าทราบ)

23
ที่อยู่ IP ของตัวแทนรีเลย์
172.16.114.41
เส้น
4
ที่อยู่ IP ของตัวแทนรีเลย์ (เช่น สวิตช์)

27
ที่อยู่ MAC ของไคลเอ็นต์
14:d6:4d:a7:c9:55
แม่มด
6
ที่อยู่ MAC ของผู้ส่งแพ็คเก็ต (ไคลเอนต์)

31
การขยายที่อยู่ฮาร์ดแวร์ไคลเอ็นต์
 
แม่มด
10
สำรองที่นั่ง. มักจะเต็มไปด้วยเลขศูนย์

41
ชื่อโฮสต์ของเซิร์ฟเวอร์
 
เส้น
64
ชื่อเซิร์ฟเวอร์ DHCP ปกติไม่ถ่ายทอด.

105
ชื่อไฟล์บูต
 
เส้น
128
ชื่อไฟล์บนเซิร์ฟเวอร์ที่ใช้โดยสเตชั่นไร้ดิสก์เมื่อทำการบูท

235
คุกกี้เมจิก
63: 82: 53: 63
แม่มด
4
หมายเลข “เวทย์มนตร์” ตามที่ระบุ ได้แก่ คุณสามารถระบุได้ว่าแพ็กเก็ตนี้เป็นของโปรโตคอล DHCP

ตัวเลือก DHCP จะไปลำดับไหนก็ได้

236
หมายเลขตัวเลือก
53
ธันวาคม
3
ตัวเลือก 53 ซึ่งกำหนดแพ็กเก็ต DHCP ประเภท 5 - DHCPACK

 
ความยาวตัวเลือก
1
ธันวาคม
1

 
ค่าตัวเลือก
5
ธันวาคม
1

 
หมายเลขตัวเลือก
1
ธันวาคม
1
ตัวเลือกในการเสนอเน็ตเวิร์กมาสก์ให้กับไคลเอ็นต์ DHCP

 
ความยาวตัวเลือก
4
ธันวาคม
1

 
ค่าตัวเลือก
255.255.224.0
เส้น
4

 
หมายเลขตัวเลือก
3
ธันวาคม
1
ตัวเลือกในการเสนอเกตเวย์เริ่มต้นให้กับไคลเอ็นต์ DHCP

 
ความยาวตัวเลือก
4
ธันวาคม
1

 
ค่าตัวเลือก
172.16.12.1
เส้น
4

 
หมายเลขตัวเลือก
6
ธันวาคม
1
ตัวเลือกในการเสนอ DHCP ให้กับไคลเอนต์ DNS

 
ความยาวตัวเลือก
4
ธันวาคม
1

 
ค่าตัวเลือก
8.8.8.8
เส้น
4

 
หมายเลขตัวเลือก
51
ธันวาคม
1
อายุการใช้งานของพารามิเตอร์เครือข่ายที่ออกในหน่วยวินาที หลังจากนั้นไคลเอ็นต์ DHCP จะต้องร้องขออีกครั้ง

 
ความยาวตัวเลือก
4
ธันวาคม
1

 
ค่าตัวเลือก
86400
ธันวาคม
4

 
หมายเลขตัวเลือก
82
ธันวาคม
1
ตัวเลือก 82 ทำซ้ำสิ่งที่มาใน DHCPDISCOVER

 
ความยาวตัวเลือก
18
ธันวาคม
1

 
ค่าตัวเลือก
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:เช่น
ธันวาคม
18

 
สิ้นสุดแพ็คเกจ
255
ธันวาคม
1
255 เป็นสัญลักษณ์ของการสิ้นสุดแพ็กเก็ต

การติดตั้ง

การติดตั้งประกอบด้วยการติดตั้งโมดูลหลามที่จำเป็นสำหรับการทำงาน ถือว่าติดตั้งและกำหนดค่า MySQL แล้ว

FreeBSD

pkg ติดตั้ง python3 python3 -m Surepip pip3 ติดตั้งตัวเชื่อมต่อ mysql

อูบุนตู

sudo apt-get ติดตั้ง python3 sudo apt-get ติดตั้ง pip3 sudo pip3 ติดตั้งตัวเชื่อมต่อ mysql

เราสร้างฐานข้อมูล MySQL อัปโหลดดัมพ์ pydhcp.sql ลงไป และกำหนดค่าไฟล์การกำหนดค่า

องค์ประกอบ

การตั้งค่าเซิร์ฟเวอร์ทั้งหมดอยู่ในไฟล์ xml ไฟล์อ้างอิง:

1.0 0.0.0.0 255.255.255.255 192.168.0.71 8600 1 255.255.255.0 192.168.0.1 โลคัลโฮสต์ ทดสอบ ทดสอบ pydhcp option_8.8.8.8_hex:sw_port82:1:20 option_22_hex:sw_port82:2:16 option_18_hex:sw_mac:82:26 40 เลือก ip,mask,router,dns จากผู้ใช้โดยที่ upper(mac)=upper('{option_3_AgentRemoteId_hex}') และ upper(port)=upper('{option_1_AgentCircuitId_port_hex}') เลือก ip,mask,router,dns จากผู้ใช้โดยที่ upper(mac)=upper('{sw_mac}') และ upper(port)=upper('{sw_port82}') เลือก ip,mask,router,dns จากผู้ใช้โดยที่ upper(mac)=upper('{ClientMacAddress}') แทรกลงในค่าประวัติ (id,dt,mac,ip,comment) (null,now(),'{ClientMacAddress}','{RequestedIpAddress}','DHCPACK/INFORM')

ตอนนี้มีรายละเอียดเพิ่มเติมเกี่ยวกับแท็ก:

ส่วน dhcpserver อธิบายการตั้งค่าพื้นฐานสำหรับการเริ่มต้นเซิร์ฟเวอร์ ได้แก่:

  • โฮสต์ - ที่อยู่ IP ใดที่เซิร์ฟเวอร์ฟังบนพอร์ต 67
  • ออกอากาศ - ip ใดที่ออกอากาศสำหรับ DHCPOFFER และ DHCPACK
  • DHCPServer - IP ของเซิร์ฟเวอร์ DHCP คืออะไร
  • LeaseTime เวลาเช่าของที่อยู่ IP ที่ออก
  • ThreadLimit - จำนวนเธรดที่ทำงานพร้อมกันเพื่อประมวลผลแพ็กเก็ต UDP ขาเข้าบนพอร์ต 67 มันควรจะช่วยในโครงการที่มีการโหลดสูง 😉
  • defaultMask,defaultRouter,defaultDNS - สิ่งที่เสนอให้กับสมาชิกตามค่าเริ่มต้นหากพบ IP ในฐานข้อมูล แต่ไม่ได้ระบุพารามิเตอร์เพิ่มเติม

ส่วน mysql:

โฮสต์ ชื่อผู้ใช้ รหัสผ่าน ชื่อฐาน - ทุกอย่างพูดเพื่อตัวเอง มีการโพสต์โครงสร้างฐานข้อมูลโดยประมาณ GitHub

ส่วนคำถาม: คำขอรับข้อเสนอ/ACK มีอธิบายไว้ที่นี่:

  • offer_count — จำนวนบรรทัดที่มีคำขอที่ส่งคืนผลลัพธ์ เช่น ip,mask,router,dns
  • offer_n - สตริงการสืบค้น หากการส่งคืนว่างเปล่า ให้ดำเนินการคำขอข้อเสนอต่อไปนี้
  • history_sql - แบบสอบถามที่เขียนไปยัง "ประวัติการอนุญาต" สำหรับผู้สมัครสมาชิก

คำขอสามารถรวมตัวแปรใดๆ จากส่วนตัวเลือกหรือตัวเลือกจากโปรโตคอล DHCP

ส่วนตัวเลือก นี่คือจุดที่น่าสนใจมากขึ้น ที่นี่เราสามารถสร้างตัวแปรที่เราสามารถใช้ได้ในภายหลังในส่วนแบบสอบถาม

ตัวอย่างเช่น:

option_82_hex:sw_port1:20:22

บรรทัดคำสั่งนี้รับทั้งบรรทัดที่มาในตัวเลือกคำขอ DHCP 82 ในรูปแบบ hex ในช่วงตั้งแต่ 20 ถึง 22 ไบต์และวางไว้ในตัวแปรใหม่ sw_port1 (สลับพอร์ตจากจุดที่คำขอมา)

option_82_hex:sw_mac:26:40

ให้กำหนดตัวแปร sw_mac โดยใช้เลขฐานสิบหกจากช่วง 26:40

คุณสามารถดูตัวเลือกที่เป็นไปได้ทั้งหมดที่สามารถนำมาใช้ในแบบสอบถามได้โดยการเริ่มต้นเซิร์ฟเวอร์ด้วยสวิตช์ -d เราจะเห็นบันทึกบางอย่างเช่นนี้:

--a แพ็กเก็ต DHCPINFORM มาถึงพอร์ต 67 จาก 0025224ad764 , b'x91xa5xe0xa3xa5xa9-x8fx8a' , ('172.30.114.25', 68) {'ClientMacAddress': '0025224ad764', 'ClientMacAddressByte': b'x00 7 %"Jxd91d' , ' HType': 'Ethernet', 'ชื่อโฮสต์': b'x5xa0xe3xa5xa9xa8-x8fx43a', 'ReqListDNS': จริง, 'ReqListDomainName': จริง, 'ReqListPerfowmRouterDiscover': จริง, 'ReqListRouter': จริง, 'ReqListStaticRoute': จริง, 'ReqListSubnetM ถาม ': จริง 'ReqListVendorSpecInfo': 0.0.0.0, 'RequestedIpAddress': '5.0', 'ผู้ขาย': b'MSFT 0025224', 'chaddr': '764ad172.30.128.13', 'ciaddr': '00' , 'ธง ': b'x00x172.30.114.25', 'giaddr': '308', 'gpoz': 6, 'hlen': 1, 'hops': 82, 'htype': 'MAC', 'magic_cookie': b'cx12Sc ', 'op': 'DHCPINFORM', 'option12': 53, 'option53': 55, 'option55': 60, 'option60': 61, 'option61': 82, 'option82': 82, ' option_12_byte': b'x01x06x00x04x00x01x00x06x02x08x00x06' b'x00x1x9eXx2exb82xad', 'option_12010600040001000602080006001_hex': '589e2eb82ad', ' option_18_len': 82 12, 'option_01_str': "b'x06x00x04x00x01x00x06x02x08x00x06x00x1x9x2eXx768exb0.0.0.0xad'", 'ผลลัพธ์': เท็จ, 'วินาที': 001, 'siaddr': '589', 'sw_mac': '2e1eb06ad', 'sw_port89': '8', 'xidbyte': b'

ดังนั้น เราสามารถรวมตัวแปรใดๆ ไว้ใน {} และจะถูกใช้ในการสืบค้น SQL

ให้เราบันทึกประวัติที่ลูกค้าได้รับที่อยู่ IP:

เซิร์ฟเวอร์ DHCP+Mysql ใน Python

เซิร์ฟเวอร์ DHCP+Mysql ใน Python

เซิร์ฟเวอร์เริ่มต้น

./pydhcpdb.py -d -c config.xml

— d โหมดเอาต์พุตคอนโซล DEBUG
- c ไฟล์กำหนดค่า <ชื่อไฟล์>

การซักถาม

และตอนนี้รายละเอียดเพิ่มเติมเกี่ยวกับการใช้งานเซิร์ฟเวอร์ใน Python มันเป็นความเจ็บปวด Python เรียนรู้ได้ทันที หลายๆ โมเมนต์ถูกสร้างขึ้นมาในรูปแบบ "ว้าว ฉันทำมันสำเร็จ" ไม่ได้รับการปรับให้เหมาะสมเลย และทิ้งไว้ในรูปแบบนี้สาเหตุหลักมาจากประสบการณ์เพียงเล็กน้อยในการพัฒนา Python ฉันจะกล่าวถึงแง่มุมที่น่าสนใจที่สุดของการใช้งานเซิร์ฟเวอร์ใน "โค้ด"

ตัวแยกวิเคราะห์ไฟล์การกำหนดค่า XML

ใช้โมดูล Python มาตรฐาน xml.dom ดูเหมือนง่าย แต่ในระหว่างการนำไปใช้งานขาดเอกสารและตัวอย่างที่ชัดเจนบนเครือข่ายที่ใช้โมดูลนี้อย่างเห็นได้ชัด

    tree = minidom.parse(gconfig["config_file"]) mconfig=tree.getElementsByTagName("mysql") สำหรับองค์ประกอบใน mconfig: gconfig["mysql_host"]=elem.getElementsByTagName("host")[0].firstChild.data gconfig["mysql_username"]=elem.getElementsByTagName("ชื่อผู้ใช้")[0].firstChild.data gconfig["mysql_password"]=elem.getElementsByTagName("password")[0].firstChild.data gconfig["mysql_basename"] =elem.getElementsByTagName("basename")[0].firstChild.data dconfig=tree.getElementsByTagName("dhcpserver") สำหรับเอเลมใน dconfig: gconfig["broadcast"]=elem.getElementsByTagName("broadcast")[0] firstChild.data gconfig["dhcp_host"]=elem.getElementsByTagName("host")[0].firstChild.data gconfig["dhcp_LeaseTime"]=elem.getElementsByTagName("LeaseTime")[0].firstChild.data gconfig[" dhcp_ThreadLimit"]=int(elem.getElementsByTagName("ThreadLimit")[0].firstChild.data) gconfig["dhcp_Server"]=elem.getElementsByTagName("DHCPServer")[0].firstChild.data gconfig["dhcp_defaultMask"] =elem.getElementsByTagName("defaultMask")[0].firstChild.data gconfig["dhcp_defaultRouter"]=elem.getElementsByTagName("defaultRouter")[0].firstChild.data gconfig["dhcp_defaultDNS"]=elem.getElementsByTagName(" defaultDNS")[0].firstChild.data qconfig=tree.getElementsByTagName("query") สำหรับเอเลมใน qconfig: gconfig["offer_count"]=elem.getElementsByTagName("offer_count")[0].firstChild.data สำหรับ num ใน ช่วง (int (gconfig ["offer_count"])): gconfig ["offer_"+str (num+1)]=elem.getElementsByTagName("offer_"+str(num+1))[0].firstChild.data gconfig ["history_sql"]=elem.getElementsByTagName("history_sql")[0].firstChild.data options=tree.getElementsByTagName("options") สำหรับองค์ประกอบในตัวเลือก: node=elem.getElementsByTagName("option") สำหรับตัวเลือกในโหนด : optionsMod.append(options.firstChild.data)

มัลติเธรด

น่าแปลกที่การใช้มัลติเธรดใน Python นั้นชัดเจนและเรียบง่ายมาก

def PacketWork(data,addr): ... # การดำเนินการแยกวิเคราะห์แพ็กเก็ตขาเข้าและตอบสนองต่อมัน ... ในขณะที่ True: data, addr = udp_socket.recvfrom(1024) # กำลังรอเธรดแพ็กเก็ต UDP = threading.Thread( target=PacketWork , args=(data,addr,)).start() # ตามมา - เราเปิดใช้ฟังก์ชัน PacketWork ที่กำหนดไว้ก่อนหน้านี้ในพื้นหลังพร้อมพารามิเตอร์ในขณะที่ threading.active_count() >gconfig["dhcp_ThreadLimit"]: time sleep(1) # ถ้าจำนวน มีเธรดที่ทำงานอยู่มากกว่าในการตั้งค่า เราจะรอจนกว่าจะมีจำนวนเธรดน้อยลง

รับ/ส่งแพ็กเก็ต DHCP

ในการสกัดกั้นแพ็กเก็ต UDP ที่ส่งผ่านการ์ดเครือข่าย คุณต้อง "เพิ่ม" ซ็อกเก็ต:

udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,socket.IPPROTO_UDP) udp_socket.bind((gconfig["dhcp_host"],67))

โดยที่ธงอยู่:

  • AF_INET - หมายความว่ารูปแบบที่อยู่จะเป็น IP: พอร์ต อาจมี AF_UNIX - โดยที่ชื่อไฟล์กำหนดที่อยู่
  • SOCK_DGRAM - หมายความว่าเราไม่ยอมรับ "แพ็กเก็ตดิบ" แต่เป็นแพ็กเก็ตที่ผ่านไฟร์วอลล์แล้วและมีแพ็กเก็ตที่ถูกตัดแต่งบางส่วน เหล่านั้น. เราได้รับเฉพาะแพ็กเก็ต UDP ที่ไม่มีส่วนประกอบ "ฟิสิคัล" ของตัวห่อแพ็กเก็ต UDP หากคุณใช้แฟล็ก SOCK_RAW คุณจะต้องแยกวิเคราะห์ "wrapper" นี้ด้วย

การส่งแพ็กเก็ตก็เหมือนกับการออกอากาศ:

                    udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #switch ซ็อกเก็ตไปที่โหมดออกอากาศ rz=udp_socket.sendto(packetack, (gconfig["broadcast"],68))

และไปยังที่อยู่ “แหล่งที่มาของพัสดุ”:

                        udp_socket.setsockopt (socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # สลับซ็อกเก็ตไปที่โหมดผู้ฟังหลายราย rz=udp_socket.sendto (packetack, addr)

โดยที่ SOL_SOCKET หมายถึง "ระดับโปรโตคอล" สำหรับตัวเลือกการตั้งค่า

, SO_BROADCAST ตัวเลือกที่แพ็คเกจหมวกกันน็อคคือ "ออกอากาศ"

  ตัวเลือก SO_REUSEADDR จะเปลี่ยนซ็อกเก็ตเป็นโหมด "ผู้ฟังจำนวนมาก" ตามทฤษฎีแล้วในกรณีนี้มันไม่จำเป็น แต่ในเซิร์ฟเวอร์ FreeBSD ตัวใดตัวหนึ่งที่ฉันทดสอบโค้ดจะไม่ทำงานหากไม่มีตัวเลือกนี้

การแยกวิเคราะห์แพ็กเก็ต DHCP

ที่นี่ฉันชอบ Python มาก ปรากฎว่านอกกรอบจะช่วยให้คุณมีความยืดหยุ่นกับโค้ดไบต์ได้ ช่วยให้สามารถแปลเป็นค่าทศนิยม สตริง และเลขฐานสิบหกได้อย่างง่ายดาย เช่น นี่คือสิ่งที่เราต้องเข้าใจโครงสร้างของแพ็คเกจจริงๆ ตัวอย่างเช่น คุณสามารถรับช่วงของไบต์ใน HEX และเพียงไบต์:

    ความละเอียด["xidhex"]=ข้อมูล[4:8].hex() ความละเอียด["xidbyte"]=ข้อมูล[4:8]

, แพ็คไบต์ลงในโครงสร้าง:

res["flags"]=pack('BB',ข้อมูล[10],ข้อมูล[11])

รับ IP จากโครงสร้าง:

res["ciaddr"]=socket.inet_ntoa(แพ็ค('BBBB',ข้อมูล[12],ข้อมูล[13],ข้อมูล[14],ข้อมูล[15]));

และในทางกลับกัน:

res=res+socket.inet_pton(socket.AF_INET, gconfig["dhcp_Server"])

นั่นคือทั้งหมดสำหรับตอนนี้😉

ที่มา: will.com

เพิ่มความคิดเห็น