penggantian server DB2DHCP (garpu saya), asli di sini, yang menjadi semakin sulit untuk dirakit untuk OS baru. Dan saya tidak suka bahwa ini adalah biner yang tidak ada cara untuk "mengubahnya sekarang"
mendapatkan server DHCP yang berfungsi dengan kemampuan untuk memilih alamat IP pelanggan menggunakan mac pelanggan atau kombinasi switch mac+port (Opsi 82)
menulis sepeda lain (Oh! ini aktivitas favoritku)
menerima komentar tentang sifat kidal Anda di Habrahabr (atau lebih baik lagi, undangan) 😉
Hasil: berhasil 😉 Diuji pada OS FreeBSD dan Ubuntu. Secara teoritis, kode tersebut dapat diminta untuk berfungsi di OS apa pun, karena Tampaknya tidak ada ikatan khusus dalam kode tersebut.
Dengan hati-hati! Masih banyak lagi yang akan datang.
Tautan ke repositori untuk amatir "sentuh hidup-hidup".
Proses instalasi, konfigurasi dan penggunaan hasil “mempelajari perangkat keras” jauh lebih rendah, dan kemudian sedikit teori tentang protokol DHCP. Untuk diriku. Dan untuk sejarah 😉
Sedikit teori
Apa itu DHCP
Ini adalah protokol jaringan yang memungkinkan perangkat mengetahui alamat IP-nya (dan parameter lain seperti gateway, DNS, dll.) dari server DHCP. Paket dipertukarkan menggunakan protokol UDP. Prinsip umum pengoperasian perangkat saat meminta parameter jaringan adalah sebagai berikut:
Perangkat (klien) mengirimkan permintaan siaran UDP (DHCPDISCOVER) ke seluruh jaringan dengan permintaan “baiklah, seseorang memberi saya alamat IP.” Selain itu, biasanya (tetapi tidak selalu) permintaan terjadi dari port 68 (sumber), dan tujuannya adalah port 67 (tujuan). Beberapa perangkat juga mengirim paket dari port 67. Alamat MAC perangkat klien disertakan dalam paket DHCPDISCOVER.
Semua server DHCP yang terletak di jaringan (dan mungkin ada beberapa di antaranya) membentuk penawaran DHCPOFFER dengan pengaturan jaringan untuk perangkat yang mengirim DHCPDISCOVER, dan juga menyiarkannya melalui jaringan. Identifikasi untuk siapa paket ini ditujukan berdasarkan alamat MAC klien yang diberikan sebelumnya dalam permintaan DHCPDISCOVER.
Klien menerima paket dengan proposal untuk pengaturan jaringan, memilih yang paling menarik (kriteria mungkin berbeda, misalnya, waktu pengiriman paket, jumlah rute perantara), dan membuat "permintaan resmi" DHCPREQUEST dengan pengaturan jaringan dari server DHCP yang disukainya. Dalam hal ini, paket dikirim ke server DHCP tertentu.
Server yang menerima DHCPREQUEST mengirimkan paket format DHCPACK, yang sekali lagi mencantumkan pengaturan jaringan yang ditujukan untuk klien ini
Selain itu, ada paket DHCPINFORM yang berasal dari klien, dan tujuannya adalah untuk memberi tahu server DHCP bahwa “klien masih hidup” dan menggunakan pengaturan jaringan yang dikeluarkan. Dalam implementasi server ini, paket-paket ini diabaikan.
Format paket
Secara umum, frame paket Ethernet terlihat seperti ini:
Dalam kasus kami, kami hanya akan mempertimbangkan data langsung dari isi paket UDP, tanpa header protokol lapisan OSI, yaitu struktur DHCP:
DHCP TEMUKAN
Jadi, proses mendapatkan alamat IP untuk suatu perangkat dimulai dengan klien DHCP mengirimkan permintaan siaran dari port 68 ke 255.255.255.255:67. Dalam paket ini, klien menyertakan alamat MAC-nya, serta apa sebenarnya yang ingin diterimanya dari server DHCP. Struktur paket dijelaskan pada tabel di bawah ini.
Tabel Struktur Paket DHCPDISCOVER
Posisi dalam paket
Nama nilai
Contoh
Pendahuluan
Byte
Klarifikasi
1
Permintaan Booting
1
kutukan
1
Jenis pesan. 1 - permintaan dari klien ke server, 2 - respons dari server ke klien
2
Jenis perangkat keras
1
kutukan
1
Jenis alamat perangkat keras, dalam protokol ini 1 - MAC
3
Panjang alamat perangkat keras
6
kutukan
1
Panjang alamat MAC perangkat
4
Hop
1
kutukan
1
Jumlah rute perantara
5
ID Transaksi
23:lih:de:1d
kutukan
4
Pengidentifikasi transaksi unik. Dihasilkan oleh klien pada awal operasi permintaan
7
Waktu kedua telah berlalu
0
kutukan
4
Waktu dalam hitungan detik sejak awal proses mendapatkan alamat
9
Bendera boot
0
kutukan
2
Bendera tertentu yang dapat diatur untuk menunjukkan parameter protokol
11
Alamat IP klien
0.0.0.0
Tali
4
Alamat IP klien (jika ada)
15
Alamat IP klien Anda
0.0.0.0
Tali
4
Alamat IP yang ditawarkan oleh server (jika tersedia)
19
Alamat IP server berikutnya
0.0.0.0
Tali
4
Alamat IP server (jika diketahui)
23
Alamat IP agen relai
172.16.114.41
Tali
4
Alamat IP agen relai (misalnya, sakelar)
27
Alamat MAC klien
14:d6:4d:a7:c9:55
kutukan
6
Alamat MAC pengirim paket (klien)
31
Padding alamat perangkat keras klien
kutukan
10
Kursi yang dipesan. Biasanya diisi dengan angka nol
41
Nama host server
Tali
64
Nama server DHCP. Biasanya tidak menular
105
Nama file boot
Tali
128
Nama file di server yang digunakan oleh stasiun tanpa disk saat booting
235
Kue ajaib
63: 82: 53: 63
kutukan
4
Nomor "ajaib", yang menurutnya, termasuk. Anda dapat menentukan bahwa paket ini milik protokol DHCP
Opsi DHCP. Bisa dalam urutan apa pun
236
Nomor opsi
53
Desember
1
Opsi 53, yang menentukan jenis paket DHCP
Nomor opsi
50
Desember
1
Alamat IP apa yang ingin diterima klien?
Panjang opsi
4
Desember
1
Nilai opsi
172.16.134.61
Tali
4
Nomor opsi
55
1
Parameter jaringan yang diminta oleh klien. Komposisinya mungkin berbeda
01 — Masker jaringan
03 - Gerbang
06 -DNS
oc — Nama host
0f - nama domain jaringan
1c - alamat permintaan siaran (siaran)
42 - Nama server TFTP
79 - Rute Statis Tanpa Kelas
Panjang opsi
8
1
Nilai opsi
01:03:06:0c:0f:1c:42:79
8
Nomor opsi
82
Desember
Opsi 82, yang mengirimkan alamat MAC perangkat pengulang dan beberapa nilai tambahan.
Paling sering, ini adalah port switch di mana klien DHCP akhir berjalan. Opsi ini berisi parameter tambahan. Byte pertama adalah nomor "subopsi", yang kedua adalah panjangnya, lalu nilainya.
Dalam hal ini, pada opsi 82, sub-opsi disarangkan:
ID Sirkuit Agen = 00:04:00:01:00:04, dengan dua byte terakhir adalah port klien DHCP tempat permintaan datang
ID Jarak Jauh Agen = 00:06:c8:be:19:93:11:48 - Alamat MAC perangkat pengulang DHCP
Panjang opsi
18
Desember
Nilai opsi
01:06
00:04:00:01:00:04
02:08
00:06:c8:be:19:93:11:48
kutukan
Akhir paket
255
Desember
1
255 melambangkan akhir dari paket
PENAWARAN DHCP
Segera setelah server menerima paket DHCPDISCOVER dan jika server melihat bahwa ia dapat menawarkan sesuatu kepada klien dari paket yang diminta, maka server akan menghasilkan respons untuk itu - DHCPDISCOVER. Responsnya dikirim ke port “dari mana asalnya”, melalui siaran, karena Saat ini klien belum memiliki alamat IP, oleh karena itu ia hanya dapat menerima paket jika dikirim melalui siaran. Klien mengenali bahwa ini adalah paket untuknya melalui alamat MAC-nya di dalam paket, serta nomor transaksi yang dia hasilkan pada saat paket pertama dibuat.
Tabel Struktur Paket DHCPOFFER
Posisi dalam paket
Nama nilai (umum)
Contoh
Pendahuluan
Byte
Klarifikasi
1
Permintaan Booting
1
kutukan
1
Jenis pesan. 1 - permintaan dari klien ke server, 2 - respons dari server ke klien
2
Jenis perangkat keras
1
kutukan
1
Jenis alamat perangkat keras, dalam protokol ini 1 - MAC
3
Panjang alamat perangkat keras
6
kutukan
1
Panjang alamat MAC perangkat
4
Hop
1
kutukan
1
Jumlah rute perantara
5
ID Transaksi
23:lih:de:1d
kutukan
4
Pengidentifikasi transaksi unik. Dihasilkan oleh klien pada awal operasi permintaan
7
Waktu kedua telah berlalu
0
kutukan
4
Waktu dalam hitungan detik sejak awal proses mendapatkan alamat
9
Bendera boot
0
kutukan
2
Bendera tertentu yang dapat diatur untuk menunjukkan parameter protokol. Dalam hal ini, 0 berarti jenis permintaan Unicast
11
Alamat IP klien
0.0.0.0
Tali
4
Alamat IP klien (jika ada)
15
Alamat IP klien Anda
172.16.134.61
Tali
4
Alamat IP yang ditawarkan oleh server (jika tersedia)
19
Alamat IP server berikutnya
0.0.0.0
Tali
4
Alamat IP server (jika diketahui)
23
Alamat IP agen relai
172.16.114.41
Tali
4
Alamat IP agen relai (misalnya, sakelar)
27
Alamat MAC klien
14:d6:4d:a7:c9:55
kutukan
6
Alamat MAC pengirim paket (klien)
31
Padding alamat perangkat keras klien
kutukan
10
Kursi yang dipesan. Biasanya diisi dengan angka nol
41
Nama host server
Tali
64
Nama server DHCP. Biasanya tidak menular
105
Nama file boot
Tali
128
Nama file di server yang digunakan oleh stasiun tanpa disk saat booting
235
Kue ajaib
63: 82: 53: 63
kutukan
4
Nomor "ajaib", yang menurutnya, termasuk. Anda dapat menentukan bahwa paket ini milik protokol DHCP
Opsi DHCP. Bisa dalam urutan apa pun
236
Nomor opsi
53
Desember
1
Opsi 53, yang mendefinisikan jenis paket DHCP 2 - DHCPOFFER
Panjang opsi
1
Desember
1
Nilai opsi
2
Desember
1
Nomor opsi
1
Desember
1
Pilihan untuk menawarkan klien DHCP masker jaringan
Panjang opsi
4
Desember
1
Nilai opsi
255.255.224.0
Tali
4
Nomor opsi
3
Desember
1
Pilihan untuk menawarkan gateway default kepada klien DHCP
Panjang opsi
4
Desember
1
Nilai opsi
172.16.12.1
Tali
4
Nomor opsi
6
Desember
1
Pilihan untuk menawarkan DHCP ke klien DNS
Panjang opsi
4
Desember
1
Nilai opsi
8.8.8.8
Tali
4
Nomor opsi
51
Desember
1
Masa pakai parameter jaringan yang dikeluarkan dalam hitungan detik, setelah itu klien DHCP harus memintanya lagi
Panjang opsi
4
Desember
1
Nilai opsi
86400
Desember
4
Nomor opsi
82
Desember
1
Opsi 82, ulangi apa yang ada di DHCPDISCOVER
Panjang opsi
18
Desember
1
Nilai opsi
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Desember
18
Akhir paket
255
Desember
1
255 melambangkan akhir dari paket
PERMINTAAN DHC
Setelah klien menerima DHCPOFFER, ia membentuk paket yang meminta parameter jaringan tidak ke semua server DHCP di jaringan, tetapi hanya ke satu server tertentu, yang penawaran DHCPOFFER-nya paling ia “sukai”. Kriteria "suka" bisa berbeda dan bergantung pada implementasi DHCP klien. Penerima permintaan ditentukan menggunakan alamat MAC server DHCP. Selain itu, paket DHCPREQUEST dapat dikirim oleh klien tanpa terlebih dahulu membuat DHCPDISCOVER, jika alamat IP server telah diperoleh sebelumnya.
Tabel Struktur Paket DHCPREQUEST
Posisi dalam paket
Nama nilai (umum)
Contoh
Pendahuluan
Byte
Klarifikasi
1
Permintaan Booting
1
kutukan
1
Jenis pesan. 1 - permintaan dari klien ke server, 2 - respons dari server ke klien
2
Jenis perangkat keras
1
kutukan
1
Jenis alamat perangkat keras, dalam protokol ini 1 - MAC
3
Panjang alamat perangkat keras
6
kutukan
1
Panjang alamat MAC perangkat
4
Hop
1
kutukan
1
Jumlah rute perantara
5
ID Transaksi
23:lih:de:1d
kutukan
4
Pengidentifikasi transaksi unik. Dihasilkan oleh klien pada awal operasi permintaan
7
Waktu kedua telah berlalu
0
kutukan
4
Waktu dalam hitungan detik sejak awal proses mendapatkan alamat
9
Bendera boot
8000
kutukan
2
Bendera tertentu yang dapat diatur untuk menunjukkan parameter protokol. Dalam hal ini, “siaran” diatur
11
Alamat IP klien
0.0.0.0
Tali
4
Alamat IP klien (jika ada)
15
Alamat IP klien Anda
172.16.134.61
Tali
4
Alamat IP yang ditawarkan oleh server (jika tersedia)
19
Alamat IP server berikutnya
0.0.0.0
Tali
4
Alamat IP server (jika diketahui)
23
Alamat IP agen relai
172.16.114.41
Tali
4
Alamat IP agen relai (misalnya, sakelar)
27
Alamat MAC klien
14:d6:4d:a7:c9:55
kutukan
6
Alamat MAC pengirim paket (klien)
31
Padding alamat perangkat keras klien
kutukan
10
Kursi yang dipesan. Biasanya diisi dengan angka nol
41
Nama host server
Tali
64
Nama server DHCP. Biasanya tidak menular
105
Nama file boot
Tali
128
Nama file di server yang digunakan oleh stasiun tanpa disk saat booting
235
Kue ajaib
63: 82: 53: 63
kutukan
4
Nomor "ajaib", yang menurutnya, termasuk. Anda dapat menentukan bahwa paket ini milik protokol DHCP
Opsi DHCP. Bisa dalam urutan apa pun
236
Nomor opsi
53
Desember
3
Opsi 53, yang mendefinisikan paket DHCP tipe 3 - DHCPREQUEST
Panjang opsi
1
Desember
1
Nilai opsi
3
Desember
1
Nomor opsi
61
Desember
1
ID Klien: 01 (untuk Ehernet) + alamat MAC klien
Panjang opsi
7
Desember
1
Nilai opsi
01:2c:ab:25:ff:72:a6
kutukan
7
Nomor opsi
60
Desember
"Pengidentifikasi kelas vendor". Dalam kasus saya, ini melaporkan versi klien DHCP. Mungkin perangkat lain memberikan sesuatu yang berbeda. Windows misalnya melaporkan MSFT 5.0
Panjang opsi
11
Desember
Nilai opsi
udhcp 0.9.8
Tali
Nomor opsi
55
1
Parameter jaringan yang diminta oleh klien. Komposisinya mungkin berbeda
01 — Masker jaringan
03 - Gerbang
06 -DNS
oc — Nama host
0f - nama domain jaringan
1c - alamat permintaan siaran (siaran)
42 - Nama server TFTP
79 - Rute Statis Tanpa Kelas
Panjang opsi
8
1
Nilai opsi
01:03:06:0c:0f:1c:42:79
8
Nomor opsi
82
Desember
1
Opsi 82, ulangi apa yang ada di DHCPDISCOVER
Panjang opsi
18
Desember
1
Nilai opsi
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Desember
18
Akhir paket
255
Desember
1
255 melambangkan akhir dari paket
DHCPACK
Sebagai konfirmasi bahwa “ya benar, ini adalah alamat IP Anda, dan saya tidak akan memberikannya kepada orang lain” dari server DHCP, paket dalam format DHCPACK dari server ke klien dilayani. Itu dikirim secara siaran seperti paket lainnya. Meskipun, dalam kode di bawah ini untuk server DHCP yang diimplementasikan dengan Python, untuk berjaga-jaga, saya menduplikasi permintaan siaran apa pun dengan mengirimkan paket ke IP klien tertentu, jika sudah diketahui. Selain itu, server DHCP tidak peduli sama sekali apakah paket DHCPACK telah sampai ke klien. Jika klien tidak menerima DHCPACK, maka setelah beberapa saat ia akan mengulangi DHCPREQUEST
Tabel Struktur Paket DHCPACK
Posisi dalam paket
Nama nilai (umum)
Contoh
Pendahuluan
Byte
Klarifikasi
1
Permintaan Booting
2
kutukan
1
Jenis pesan. 1 - permintaan dari klien ke server, 2 - respons dari server ke klien
2
Jenis perangkat keras
1
kutukan
1
Jenis alamat perangkat keras, dalam protokol ini 1 - MAC
3
Panjang alamat perangkat keras
6
kutukan
1
Panjang alamat MAC perangkat
4
Hop
1
kutukan
1
Jumlah rute perantara
5
ID Transaksi
23:lih:de:1d
kutukan
4
Pengidentifikasi transaksi unik. Dihasilkan oleh klien pada awal operasi permintaan
7
Waktu kedua telah berlalu
0
kutukan
4
Waktu dalam hitungan detik sejak awal proses mendapatkan alamat
9
Bendera boot
8000
kutukan
2
Bendera tertentu yang dapat diatur untuk menunjukkan parameter protokol. Dalam hal ini, “siaran” diatur
11
Alamat IP klien
0.0.0.0
Tali
4
Alamat IP klien (jika ada)
15
Alamat IP klien Anda
172.16.134.61
Tali
4
Alamat IP yang ditawarkan oleh server (jika tersedia)
19
Alamat IP server berikutnya
0.0.0.0
Tali
4
Alamat IP server (jika diketahui)
23
Alamat IP agen relai
172.16.114.41
Tali
4
Alamat IP agen relai (misalnya, sakelar)
27
Alamat MAC klien
14:d6:4d:a7:c9:55
kutukan
6
Alamat MAC pengirim paket (klien)
31
Padding alamat perangkat keras klien
kutukan
10
Kursi yang dipesan. Biasanya diisi dengan angka nol
41
Nama host server
Tali
64
Nama server DHCP. Biasanya tidak menular
105
Nama file boot
Tali
128
Nama file di server yang digunakan oleh stasiun tanpa disk saat booting
235
Kue ajaib
63: 82: 53: 63
kutukan
4
Nomor "ajaib", yang menurutnya, termasuk. Anda dapat menentukan bahwa paket ini milik protokol DHCP
Opsi DHCP. Bisa dalam urutan apa pun
236
Nomor opsi
53
Desember
3
Opsi 53, yang mendefinisikan paket DHCP tipe 5 - DHCPACK
Panjang opsi
1
Desember
1
Nilai opsi
5
Desember
1
Nomor opsi
1
Desember
1
Pilihan untuk menawarkan klien DHCP masker jaringan
Panjang opsi
4
Desember
1
Nilai opsi
255.255.224.0
Tali
4
Nomor opsi
3
Desember
1
Pilihan untuk menawarkan gateway default kepada klien DHCP
Panjang opsi
4
Desember
1
Nilai opsi
172.16.12.1
Tali
4
Nomor opsi
6
Desember
1
Pilihan untuk menawarkan DHCP ke klien DNS
Panjang opsi
4
Desember
1
Nilai opsi
8.8.8.8
Tali
4
Nomor opsi
51
Desember
1
Masa pakai parameter jaringan yang dikeluarkan dalam hitungan detik, setelah itu klien DHCP harus memintanya lagi
Panjang opsi
4
Desember
1
Nilai opsi
86400
Desember
4
Nomor opsi
82
Desember
1
Opsi 82, ulangi apa yang ada di DHCPDISCOVER
Panjang opsi
18
Desember
1
Nilai opsi
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Desember
18
Akhir paket
255
Desember
1
255 melambangkan akhir dari paket
Instalasi
Instalasi sebenarnya terdiri dari instalasi modul python yang diperlukan untuk bekerja. Diasumsikan MySQL sudah terinstal dan dikonfigurasi.
Kami membuat database MySQL, mengunggah dump pydhcp.sql ke dalamnya, dan mengkonfigurasi file konfigurasi.
Konfigurasi
Semua pengaturan server ada dalam file xml. Berkas referensi:
1.0 0.0.0.0 255.255.255.255 192.168.0.71 8600 1 255.255.255.0 192.168.0.1 host lokal tes tes pydhcp opsi_8.8.8.8_hex:sw_port82:1:20 pilihan_22_hex:sw_port82:2:16 option_18_hex:sw_mac:82:26 40 pilih ip,mask,router,dns dari pengguna di mana upper(mac)=upper('{option_3_AgentRemoteId_hex}') dan upper(port)=upper('{option_1_AgentCircuitId_port_hex}') pilih ip,mask,router,dns dari pengguna di mana upper(mac)=upper('{sw_mac}') dan upper(port)=upper('{sw_port82}') pilih ip,mask,router,dns dari pengguna di mana upper(mac)=upper('{ClientMacAddress}') masukkan ke dalam nilai riwayat (id,dt,mac,ip,comment) (null,now(),'{ClientMacAddress}','{RequestedIpAddress}','DHCPACK/INFORM')
Sekarang lebih detail tentang tag:
Pada bagian dhcpserver menjelaskan tentang pengaturan dasar untuk memulai server, yaitu:
host - alamat IP apa yang didengarkan server pada port 67
siaran - ip mana yang disiarkan untuk DHCPOFFER dan DHCPACK
DHCPServer - apa ip server DHCP
LeaseTime waktu sewa dari alamat IP yang dikeluarkan
ThreadLimit - berapa banyak thread yang berjalan secara bersamaan untuk memproses paket UDP yang masuk pada port 67. Ini seharusnya membantu proyek dengan beban tinggi 😉
defaultMask,defaultRouter,defaultDNS - apa yang ditawarkan kepada pelanggan secara default jika IP ditemukan di database, tetapi parameter tambahan tidak ditentukan untuknya
bagian mysql:
host, nama pengguna, kata sandi, nama dasar - semuanya berbicara sendiri. Perkiraan struktur database diposting GitHub
Bagian kueri: permintaan untuk menerima PENAWARAN/ACK dijelaskan di sini:
offer_count — jumlah baris dengan permintaan yang mengembalikan hasil seperti ip,mask,router,dns
offer_n — string kueri. Jika pengembalian kosong, maka jalankan permintaan penawaran berikut
history_sql - kueri yang menulis, misalnya, ke "riwayat otorisasi" untuk pelanggan
Permintaan dapat menyertakan variabel apa pun dari bagian opsi atau opsi dari protokol DHCP.
Bagian opsi. Di sinilah hal menjadi lebih menarik. Di sini kita bisa membuat variabel yang nantinya bisa kita gunakan di bagian query.
Sebagai contoh:
option_82_hex:sw_port1:20:22
, baris perintah ini mengambil seluruh baris yang datang dalam opsi permintaan DHCP 82, dalam format hex, dalam kisaran dari 20 hingga 22 byte inklusif dan memasukkannya ke dalam variabel baru sw_port1 (beralih port dari mana permintaan datang)
option_82_hex:sw_mac:26:40
, tentukan variabel sw_mac, ambil hex dari rentang 26:40
Anda dapat melihat semua kemungkinan opsi yang dapat digunakan dalam kueri dengan memulai server dengan tombol -d. Kita akan melihat sesuatu seperti log ini:
Oleh karena itu, kita bisa menggabungkan variabel apa pun dalam {} dan variabel tersebut akan digunakan dalam kueri SQL.
Mari kita catat riwayat bahwa klien menerima alamat IP:
Server mulai
./pydhcpdb.py -d -c config.xml
— d mode keluaran konsol DEBUG
- c file konfigurasi <nama file>
Tanya jawab
Dan sekarang detail lebih lanjut tentang implementasi server dengan Python. Ini menyakitkan. Python dipelajari dengan cepat. Banyak momen yang dibuat dengan gaya “wow, entah bagaimana saya berhasil.” Tidak dioptimalkan sama sekali, dan dibiarkan dalam bentuk ini terutama karena sedikit pengalaman dalam pengembangan Python. Saya akan membahas aspek paling menarik dari implementasi server dalam "kode".
Pengurai file konfigurasi XML
Modul Python standar xml.dom digunakan. Tampaknya sederhana, tetapi selama implementasi terdapat kurangnya dokumentasi dan contoh yang jelas di jaringan yang menggunakan modul ini.
tree = minidom.parse(gconfig["config_file"]) mconfig=tree.getElementsByTagName("mysql") untuk elem di mconfig: gconfig["mysql_host"]=elem.getElementsByTagName("host")[0].firstChild.data gconfig["mysql_username"]=elem.getElementsByTagName("username")[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") untuk elem di 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") untuk elem di qconfig: gconfig["offer_count"]=elem.getElementsByTagName("offer_count")[0].firstChild.data untuk num in rentang(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") untuk elem dalam opsi: node=elem.getElementsByTagName("option") untuk opsi dalam node : optionsMod.append(options.firstChild.data)
Multithread
Anehnya, multithreading dengan Python diimplementasikan dengan sangat jelas dan sederhana.
def PacketWork(data,addr): ... # implementasi parsing paket masuk dan meresponnya... while True: data, addr = udp_socket.recvfrom(1024) # menunggu paket UDP thread = threading.Thread( target=PacketWork , args=(data,addr,)).start() # yang muncul - kami meluncurkan fungsi PacketWork yang telah ditentukan sebelumnya di latar belakang dengan parameter saat threading.active_count() >gconfig["dhcp_ThreadLimit"]: waktu. tidur(1) # jika jumlah thread yang berjalan lebih banyak daripada yang ada di pengaturan, kita tunggu hingga jumlahnya lebih sedikit
Menerima/mengirim paket DHCP
Untuk mencegat paket UDP yang datang melalui kartu jaringan, Anda perlu “menaikkan” soket:
AF_INET - berarti format alamatnya adalah IP: port. Mungkin juga ada AF_UNIX - yang alamatnya diberikan berdasarkan nama file.
SOCK_DGRAM - berarti kami tidak menerima "paket mentah", tetapi paket yang telah melewati firewall, dan dengan paket yang dipotong sebagian. Itu. kami hanya menerima paket UDP tanpa komponen “fisik” dari pembungkus paket UDP. Jika Anda menggunakan flag SOCK_RAW, Anda juga perlu mengurai “wrapper” ini.
Mengirim paket bisa seperti siaran:
udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #alihkan soket ke mode siaran rz=udp_socket.sendto(packetack, (gconfig["broadcast"],68))
, dan ke alamat “dari mana paket itu berasal”:
udp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # alihkan soket ke mode multi-listener rz=udp_socket.sendto(packetack, addr)
, di mana SOL_SOCKET berarti “tingkat protokol” untuk opsi pengaturan,
, SO_BROADCAST pilihan paket helmnya adalah “broadcast”
, Opsi SO_REUSEADDR mengalihkan soket ke mode "banyak pendengar". Secara teori, hal ini tidak diperlukan dalam kasus ini, tetapi pada salah satu server FreeBSD yang saya uji, kode tidak akan berfungsi tanpa opsi ini.
Mengurai paket DHCP
Di sinilah saya sangat menyukai Python. Ternyata di luar kotak itu memungkinkan Anda menjadi cukup fleksibel dengan bytecode. Memungkinkannya untuk dengan mudah diterjemahkan ke dalam nilai desimal, string dan hex - mis. inilah yang sebenarnya kita perlukan untuk memahami struktur paket. Jadi, misalnya, Anda bisa mendapatkan rentang byte dalam HEX dan hanya byte: