
Selle projekti eesmÀrgiks oli:
- DHCP protokolli uurimine IPv4 vÔrgus
- Python'i Ă”ppimine (veidi rohkem kui nullist đ )
- serveri asendamine (minu fork), originaal , mille kokkupanemine uue operatsioonisĂŒsteemi jaoks muutub ĂŒha keerulisemaks. Ja ei meeldi, et binaarfaili ei ole vĂ”imalik "vahetada praegu"
- töökorras DHCP serveri saamine, mis vÔimaldab IP aadressi valimist abonendi pÔhjal tema MAC aadressi vÔi MAC aadressi + porti kombinatsiooni (Valik 82) kaudu
- jÀrgmise ratta kirjutamine (O! see on minu lemmiktegevus)
- oma kohmakuse tĂ”ttu saanud kriitikat HabrHabr'is (vĂ”i veel parem - kutse) đ
Tulemus: töötab đ Katsetatud FreeBSD ja Ubuntu operatsioonisĂŒsteemidel. Teoreetiliselt vĂ”iks koodi kĂ€itada igas operatsioonisĂŒsteemis, kuna koodis ei tundu olevat spetsiifilisi seoseid.
Kasutage ettevaatlikult! Edasi on palju.
Link teaduslikku repositooriumisse huvilistele .
Installeerimise, seadistamise ja tulemuse kasutamise protsess "materjali uurimisest" on allpool, ja seejĂ€rel vĂ€ike teooria DHCP protokolli kohta. Endale. Ja ajaloo nimel đ
Veidi teooriat
Mis on DHCP
See on vĂ”rgu protokoll, mis vĂ”imaldab seadmel teada saada oma IP aadressi (ja muid parameetreid nagu lĂŒĂŒs, DNS jne) DHCP serverilt. Pakettide vahetus toimub UDP protokolli kaudu. Seadme töö pĂ”himĂ”te vĂ”rgu parameetrite kĂŒsimisel on jĂ€rgmine:
- Seade (klient) saadab laienduslikku UDP pĂ€ringut (DHCPDISCOVER) lĂ€bi kogu vĂ”rgu kĂŒsimisega "kas keegi, andke mulle IP aadress". Tavaliselt (kuid mitte alati) toimub pĂ€ring 68 porti kaudu (allikas), ja sihtkoht on 67 port (sihtkoht). MĂ”ned seadmed saadavad pakette ka 67 porti kaudu. DHCPDISCOVER paketi sees on kliendi seadme MAC aadress.
- KÔik DHCP serverid, mis asuvad vÔrgus (ja neid vÔib olla mitu), koostavad seadmele, kes saadab DHCPDISCOVER, DHCPOFFER pakkumise koos vÔrgu seadistustega, ja saadavad selle laiaulatuslikult vÔrku. Paketi identifitseerimine, kellele see pakett on mÔeldud, toimub eelnevalt DHCPDISCOVER pÀringus esitatud kliendi MAC aadressi pÔhjal.
- Kliendi seadmed saavad vÔrguseadistuste pakkumisi, valivad neist kÔige atraktiivsema (kriteeriumid vÔivad olla erinevad, sealhulgas pakkumise kohaletoimetamise aeg ja vahepeatuste arv) ja saadavad valitud DHCP serverile "ametliku pÀringu" DHCPREQUEST koos vÔrguseadistustega. Sel juhul suunatakse pakk juba konkreetsele DHCP serverile.
- Server, mis sai DHCPREQUEST-i, saadab paketi kujul DHCPACK, milles loetletakse uuesti vÔrguseadistused, mis on mÔeldud antud kliendile.

Lisaks on olemas DHCPINFORM paketid, mida saadetakse kliendi poolt, mille eesmÀrk on teavitada DHCP serverit, et "klient on elus" ja kasutab antud vÔrguseadistusi. Antud serveri rakenduses ignoreeritakse neid pakette.
Pakkide formaat
KokkuvÔttes nÀeb Etherneti paketi raam vÀlja umbes nii:
![]()
KĂ€esolevas juhul vaatame ainult UDP paketi sisu andmeid, ilma OSI taseme protokollide pealkirjadeta, nimelt DHCP struktuuri:
DHCPDISCOVER
Seega algab IP-aadressi saamise protsess seadme jaoks sellega, et DHCP klient saadab laialdaselt pÀringu pordilt 68 aadressile 255.255.255.255:67. Selles pakendis sisaldab klient oma MAC aadressi ja ka seda, mida ta soovib DHCP serverilt saada. Paketi struktuur on kirjeldatud allpool olevas tabelis.
DHCPDISCOVER paketi struktuuri tabel
Positsioon paketis
VÀÀrtuse nimi
NĂ€ide
Vaade
Bait
Selgitus
1
Boot Request
1
Hex
1
SĂ”numi tĂŒĂŒp. 1 â pĂ€ring kliendilt serverile, 2 â vastus serverilt kliendile
2
Riistvara tĂŒĂŒp
1
Hex
1
Riistvara aadressi tĂŒĂŒp, selles protokollis 1 â MAC
3
Riistvara aadressi pikkus
6
Hex
1
Seadme MAC aadressi pikkus
4
Hops
1
Hex
1
Vahepeatuste arv
5
Tehingu ID
23:cf:de:1d
Hex
4
Tehingu unikaalne identifikaator. Generatsioon toimub kliendi poolt pÀringu alguses
7
Kulu sekundites
0
Hex
4
Aeg sekundites alates aadressi saamise protsessi algusest
9
Bootp lipud
0
Hex
2
MÔned lipud, mida saab seadistada protokolli parameetrite nÀitamiseks
11
Kliendi IP aadress
0.0.0.0
Rida
4
Kliendi IP aadress (kui on)
15
Teie kliendi IP aadress
0.0.0.0
Rida
4
IP aadress, mille server on pakkunud (kui on)
19
JĂ€rgmise serveri IP aadress
0.0.0.0
Rida
4
Serveri IP aadress (kui teada)
23
Ălekandeagendi IP aadress
172.16.114.41
Rida
4
Ălekandeagendi IP aadress (nĂ€iteks lĂŒliti)
27
Kliendi MAC aadress
14:d6:4d:a7:c9:55
Hex
6
Paketi saatja MAC aadress (klient)
31
Kliendi riistvara aadressi padjand
Â
Hex
10
Reserveeritud koht. Tavaliselt tÀidetud nullidega
41
Serveri hostinimi
Â
Rida
64
DHCP serveri nimi. Tavernialt see tavaliselt ei edastata
105
Boot failinimi
Â
Rida
128
Serveris failinimi, mida kasutatakse ketta vabadusjaamade kÀivitamisel
235
Magic cookie
63:82:53:63
Hex
4
«Magi» number, mille jÀrgi on vÔimalik tuvastada, et see pakett kuulub DHCP protokolli
DHCP valikud. Need vÔivad olla igas jÀrjekorras
236
Valiku number
53
Dec
1
Valik 53, mis mÀÀrab DHCP paketi tĂŒĂŒbi
1 â DHCPDISCOVER
3 â DHCPREQUEST
2 â DHCPOFFER
5 â DHCPACK
8 â DHCPINFORM
Â
Valiku pikkus
1
Dec
1
Â
Valiku vÀÀrtus
1
Dec
1
Â
Valiku number
50
Dec
1
Millise IP-aadressi soovib klient saada
Â
Valiku pikkus
4
Dec
1
Â
Valiku vÀÀrtus
172.16.134.61
Rida
4
Â
Valiku number
55
Â
1
Kliendi taotletavad vÔrgu parameetrid. Koostis vÔib olla erinev
01 â Alamside mask
03 â LĂŒkand
06 â DNS
oc â Hostinimi
0f â vĂ”rgu domeeninimi
1c â laiuskande aadress (broadcaster)
42 â TFTP serveri nimi
79 â MÀÀratlemata staatiline marsruut
Â
Valiku pikkus
8
Â
1
Â
Valiku vÀÀrtus
01:03:06:0c:0f:1c:42:79
Â
8
Â
Valiku number
82
Dec
Â
Valik 82, milles edastatakse seadme MAC-aadress â kordustootja ja mĂ”ned tĂ€iendavad vÀÀrtused.
Tavaliselt â lĂŒliti port, millel töötab lĂ”ppkliendi DHCP. Selle valiku sees on 'peidetud' tĂ€iendavad parameetrid. Esimene bait â 'alamvaliku' number, teine selle pikkus, seejĂ€rel selle vÀÀrtus.
Selles suhtes on valikus 82 peidetud alamvalikud:
Agent Circuit ID = 00:04:00:01:00:04, kus viimased kaks baidi on DHCP kliendi port, kust pÀring tuli
Agent Remote ID = 00:06:c8:be:19:93:11:48 â DHCP kordustootja MAC-aadress
Â
Valiku pikkus
18
Dec
Â
Â
Valiku vÀÀrtus
01:06
00:04:00:01:00:04
02:08
00:06:c8:be:19:93:11:48
Hex
Â
Â
Paketi lÔpp
255
Dec
1
255 sĂŒmbolit tĂ€histab paketi lĂ”ppu
DHCPOFFER
Niipea, kui server saab paketi DHCPDISCOVER ja nĂ€eb, et tal on vĂ”imalik kliendile pakkuda midagi taotletust, genereerib ta vastuse â DHCPDISCOVER. Vastus saadetakse porti, kust see tuli, broadcastina, kuna kliendil pole hetkel IP-aadressi ja seega saab ta paketti vastu vĂ”tta ainult siis, kui see saadetakse laiale ringile. Klient tuvastab, et see pakett on talle mĂ”eldud, tema MAC-aadressi ja tehingu numbri pĂ”hjal, mille ta genereerib esimese paketi loomise hetkel.
DHCPOFFER paketi struktuuri tabel
Positsioon paketis
VÀÀrtuse nimi (tavaline)
NĂ€ide
Vaade
Bait
Selgitus
1
Boot Request
1
Hex
1
SĂ”numi tĂŒĂŒp. 1 â pĂ€ring kliendilt serverile, 2 â vastus serverilt kliendile
2
Riistvara tĂŒĂŒp
1
Hex
1
Riistvara aadressi tĂŒĂŒp, selles protokollis 1 â MAC
3
Riistvara aadressi pikkus
6
Hex
1
Seadme MAC aadressi pikkus
4
Hops
1
Hex
1
Vahepeatuste arv
5
Tehingu ID
23:cf:de:1d
Hex
4
Tehingu unikaalne identifikaator. Generatsioon toimub kliendi poolt pÀringu alguses
7
Kulu sekundites
0
Hex
4
Aeg sekundites alates aadressi saamise protsessi algusest
9
Bootp lipud
0
Hex
2
MÔned lipud, mis vÔivad olla mÀÀratud protokolli parameetrite nÀitamiseks. Antud juhul tÀhendab 0 unicast'i pÀringut
11
Kliendi IP aadress
0.0.0.0
Rida
4
Kliendi IP aadress (kui on)
15
Teie kliendi IP aadress
172.16.134.61
Rida
4
IP aadress, mille server on pakkunud (kui on)
19
JĂ€rgmise serveri IP aadress
0.0.0.0
Rida
4
Serveri IP aadress (kui teada)
23
Ălekandeagendi IP aadress
172.16.114.41
Rida
4
Ălekandeagendi IP aadress (nĂ€iteks lĂŒliti)
27
Kliendi MAC aadress
14:d6:4d:a7:c9:55
Hex
6
Paketi saatja MAC aadress (klient)
31
Kliendi riistvara aadressi padjand
Â
Hex
10
Reserveeritud koht. Tavaliselt tÀidetud nullidega
41
Serveri hostinimi
Â
Rida
64
DHCP serveri nimi. Tavernialt see tavaliselt ei edastata
105
Boot failinimi
Â
Rida
128
Serveris failinimi, mida kasutatakse ketta vabadusjaamade kÀivitamisel
235
Magic cookie
63:82:53:63
Hex
4
«Magi» number, mille jÀrgi on vÔimalik tuvastada, et see pakett kuulub DHCP protokolli
DHCP valikud. Need vÔivad olla igas jÀrjekorras
236
Valiku number
53
Dec
1
Valik 53, mis mÀÀrab DHCP paketi tĂŒĂŒbi 2 â DHCPOFFER
Â
Valiku pikkus
1
Dec
1
Â
Valiku vÀÀrtus
2
Dec
1
Â
Valiku number
1
Dec
1
Valik, mis pakub DHCP kliendile alamside maski
Â
Valiku pikkus
4
Dec
1
Â
Valiku vÀÀrtus
255.255.224.0
Rida
4
Â
Valiku number
3
Dec
1
Valik, mis pakub DHCP kliendile vaike lĂŒkandi
Â
Valiku pikkus
4
Dec
1
Â
Valiku vÀÀrtus
172.16.12.1
Rida
4
Â
Valiku number
6
Dec
1
Valik, mis pakub DHCP kliendile DNS
Â
Valiku pikkus
4
Dec
1
Â
Valiku vÀÀrtus
8.8.8.8
Rida
4
Â
Valiku number
51
Dec
1
VÔrgu parameetrite kehtivusaeg sekundites, mille pÀrast peab DHCP klient taotlema neid uuesti
Â
Valiku pikkus
4
Dec
1
Â
Valiku vÀÀrtus
86400
Dec
4
Â
Valiku number
82
Dec
1
Valik 82, kordab seda, mis tuli DHCPDISCOVER'is
Â
Valiku pikkus
18
Dec
1
Â
Valiku vÀÀrtus
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Dec
18
Â
Paketi lÔpp
255
Dec
1
255 sĂŒmbolit tĂ€histab paketi lĂ”ppu
DHCPREQUEST
PĂ€rast seda, kui klient on saanud DHCPOFFER-i, koostab ta paketi vĂ”rgu parameetrite taotlemiseks mitte kĂ”igilt DHCP serveritelt, vaid ainult ĂŒhe konkreetse serveri jaoks, kelle DHCPOFFER pakkumine talle kĂ”ige rohkem âmeeldisâ. Kriteeriumid âmeeldimiseâ jaoks vĂ”ivad olla erinevad ja sĂ”ltuvad DHCP kliendi teostusest. VastuvĂ”tja antakse teada DHCP serveri MAC-aadressi kaudu. Samuti vĂ”ib DHCPREQUEST pakett kliendi saadetud olla ka ilma eelneva DHCPDISCOVER-i vormistamiseta, kui IP-aadress serverilt on juba varem saadud.
DHCPREQUEST paketi struktuuri tabel
Positsioon paketis
VÀÀrtuse nimi (tavaline)
NĂ€ide
Vaade
Bait
Selgitus
1
Boot Request
1
Hex
1
SĂ”numi tĂŒĂŒp. 1 â pĂ€ring kliendilt serverile, 2 â vastus serverilt kliendile
2
Riistvara tĂŒĂŒp
1
Hex
1
Riistvara aadressi tĂŒĂŒp, selles protokollis 1 â MAC
3
Riistvara aadressi pikkus
6
Hex
1
Seadme MAC aadressi pikkus
4
Hops
1
Hex
1
Vahepeatuste arv
5
Tehingu ID
23:cf:de:1d
Hex
4
Tehingu unikaalne identifikaator. Generatsioon toimub kliendi poolt pÀringu alguses
7
Kulu sekundites
0
Hex
4
Aeg sekundites alates aadressi saamise protsessi algusest
9
Bootp lipud
8000
Hex
2
MĂ”ned lipud, mida saab seadistada, et nĂ€idata protokolli parameetreid. Antud juhul on seadistatud âbroadcastâ
11
Kliendi IP aadress
0.0.0.0
Rida
4
Kliendi IP aadress (kui on)
15
Teie kliendi IP aadress
172.16.134.61
Rida
4
IP aadress, mille server on pakkunud (kui on)
19
JĂ€rgmise serveri IP aadress
0.0.0.0
Rida
4
Serveri IP aadress (kui teada)
23
Ălekandeagendi IP aadress
172.16.114.41
Rida
4
Ălekandeagendi IP aadress (nĂ€iteks lĂŒliti)
27
Kliendi MAC aadress
14:d6:4d:a7:c9:55
Hex
6
Paketi saatja MAC aadress (klient)
31
Kliendi riistvara aadressi padjand
Â
Hex
10
Reserveeritud koht. Tavaliselt tÀidetud nullidega
41
Serveri hostinimi
Â
Rida
64
DHCP serveri nimi. Tavernialt see tavaliselt ei edastata
105
Boot failinimi
Â
Rida
128
Serveris failinimi, mida kasutatakse ketta vabadusjaamade kÀivitamisel
235
Magic cookie
63:82:53:63
Hex
4
«Magi» number, mille jÀrgi on vÔimalik tuvastada, et see pakett kuulub DHCP protokolli
DHCP valikud. Need vÔivad olla igas jÀrjekorras
236
Valiku number
53
Dec
3
Valik 53, mis mÀÀratleb DHCP paketi tĂŒĂŒbi 3 â DHCPREQUEST
Â
Valiku pikkus
1
Dec
1
Â
Valiku vÀÀrtus
3
Dec
1
Â
Valiku number
61
Dec
1
Kliendi identifikaator: 01 (Etherneti jaoks) + kliendi MAC-aadress
Â
Valiku pikkus
7
Dec
1
Â
Valiku vÀÀrtus
01:2c:ab:25:ff:72:a6
Hex
7
Â
Valiku number
60
Dec
Â
"Vendor class identifier". Minu puhul teatab see DHCP kliendi versiooni. Teised seadmed vÔivad tagastada midagi muud. NÀiteks Windows teatab MSFT 5.0
Â
Valiku pikkus
11
Dec
Â
Â
Valiku vÀÀrtus
udhcp 0.9.8
Rida
Â
Â
Valiku number
55
Â
1
Kliendi taotletavad vÔrgu parameetrid. Koostis vÔib olla erinev
01 â Alamside mask
03 â LĂŒkand
06 â DNS
oc â Hostinimi
0f â vĂ”rgu domeeninimi
1c â laiuskande aadress (broadcaster)
42 â TFTP serveri nimi
79 â MÀÀratlemata staatiline marsruut
Â
Valiku pikkus
8
Â
1
Â
Valiku vÀÀrtus
01:03:06:0c:0f:1c:42:79
Â
8
Â
Valiku number
82
Dec
1
Valik 82, kordab seda, mis tuli DHCPDISCOVER'is
Â
Valiku pikkus
18
Dec
1
Â
Valiku vÀÀrtus
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Dec
18
Â
Paketi lÔpp
255
Dec
1
255 sĂŒmbolit tĂ€histab paketi lĂ”ppu
DHCPACK
Kinnituseks, et "jah, see on sinu IP-aadress ja ma ei anna seda enam kellelegi", saadab DHCP server paketina DHCPACK kliendile. See saadetakse nagu kÔik teised paketid laialdaselt. Kuigi allpool toodud koodis on Pythonis implementeeritud DHCP server, dubleerin ma igaks juhuks iga laiaulatuslikku taotlust, saates paketi konkreetsele IP-aadressile, kui see on juba teada. Samuti ei huvita DHCP serverit, kas DHCPACK pakett jÔudis kliendile. Kui klient ei saa DHCPACK-i, kordab ta mÔne aja pÀrast lihtsalt DHCPREQUEST-i.
DHCPACK paketi struktuuri tabel
Positsioon paketis
VÀÀrtuse nimi (tavaline)
NĂ€ide
Vaade
Bait
Selgitus
1
Boot Request
2
Hex
1
SĂ”numi tĂŒĂŒp. 1 â pĂ€ring kliendilt serverile, 2 â vastus serverilt kliendile
2
Riistvara tĂŒĂŒp
1
Hex
1
Riistvara aadressi tĂŒĂŒp, selles protokollis 1 â MAC
3
Riistvara aadressi pikkus
6
Hex
1
Seadme MAC aadressi pikkus
4
Hops
1
Hex
1
Vahepeatuste arv
5
Tehingu ID
23:cf:de:1d
Hex
4
Tehingu unikaalne identifikaator. Generatsioon toimub kliendi poolt pÀringu alguses
7
Kulu sekundites
0
Hex
4
Aeg sekundites alates aadressi saamise protsessi algusest
9
Bootp lipud
8000
Hex
2
MĂ”ned lipud, mida saab seadistada, et nĂ€idata protokolli parameetreid. Antud juhul on seadistatud âbroadcastâ
11
Kliendi IP aadress
0.0.0.0
Rida
4
Kliendi IP aadress (kui on)
15
Teie kliendi IP aadress
172.16.134.61
Rida
4
IP aadress, mille server on pakkunud (kui on)
19
JĂ€rgmise serveri IP aadress
0.0.0.0
Rida
4
Serveri IP aadress (kui teada)
23
Ălekandeagendi IP aadress
172.16.114.41
Rida
4
Ălekandeagendi IP aadress (nĂ€iteks lĂŒliti)
27
Kliendi MAC aadress
14:d6:4d:a7:c9:55
Hex
6
Paketi saatja MAC aadress (klient)
31
Kliendi riistvara aadressi padjand
Â
Hex
10
Reserveeritud koht. Tavaliselt tÀidetud nullidega
41
Serveri hostinimi
Â
Rida
64
DHCP serveri nimi. Tavernialt see tavaliselt ei edastata
105
Boot failinimi
Â
Rida
128
Serveris failinimi, mida kasutatakse ketta vabadusjaamade kÀivitamisel
235
Magic cookie
63:82:53:63
Hex
4
«Magi» number, mille jÀrgi on vÔimalik tuvastada, et see pakett kuulub DHCP protokolli
DHCP valikud. Need vÔivad olla igas jÀrjekorras
236
Valiku number
53
Dec
3
Valik 53, mis mÀÀratleb DHCP paketi tĂŒĂŒbi 5 â DHCPACK
Â
Valiku pikkus
1
Dec
1
Â
Valiku vÀÀrtus
5
Dec
1
Â
Valiku number
1
Dec
1
Valik, mis pakub DHCP kliendile alamside maski
Â
Valiku pikkus
4
Dec
1
Â
Valiku vÀÀrtus
255.255.224.0
Rida
4
Â
Valiku number
3
Dec
1
Valik, mis pakub DHCP kliendile vaike lĂŒkandi
Â
Valiku pikkus
4
Dec
1
Â
Valiku vÀÀrtus
172.16.12.1
Rida
4
Â
Valiku number
6
Dec
1
Valik, mis pakub DHCP kliendile DNS
Â
Valiku pikkus
4
Dec
1
Â
Valiku vÀÀrtus
8.8.8.8
Rida
4
Â
Valiku number
51
Dec
1
VÔrgu parameetrite kehtivusaeg sekundites, mille pÀrast peab DHCP klient taotlema neid uuesti
Â
Valiku pikkus
4
Dec
1
Â
Valiku vÀÀrtus
86400
Dec
4
Â
Valiku number
82
Dec
1
Valik 82, kordab seda, mis tuli DHCPDISCOVER'is
Â
Valiku pikkus
18
Dec
1
Â
Valiku vÀÀrtus
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Dec
18
Â
Paketi lÔpp
255
Dec
1
255 sĂŒmbolit tĂ€histab paketi lĂ”ppu
Paigaldamine
Seadistamine seisneb tegelikult vajalike Python moodulite installimises. Eeldatakse, et MySQL on juba installitud ja seadistatud.
FreeBSD
pkg install python3 python3 -m ensurepip pip3 install mysql-connector
Ubuntu
sudo apt-get install python3 sudo apt-get install pip3 sudo pip3 install mysql-connector
Loo MySQL andmebaas, lae sinna pydhcp.sql dump, seadista konfiguratsioonifail.
Konfiguratsioon
KÔik serveri seaded on xml-formaadis failis. Viidatud fail:
0.0.0.0
255.255.255.255
192.168.0.71
8600
1
255.255.255.0
192.168.0.1
8.8.8.8
localhost
test
test
pydhcp
option_82_hex:sw_port1:20:22
option_82_hex:sw_port2:16:18
option_82_hex:sw_mac:26:40
3
select ip,mask,router,dns from users where upper(mac)=upper('{option_82_AgentRemoteId_hex}') and upper(port)=upper('{option_82_AgentCircuitId_port_hex}')
select ip,mask,router,dns from users where upper(mac)=upper('{sw_mac}') and upper(port)=upper('{sw_port2}')
select ip,mask,router,dns from users where upper(mac)=upper('{ClientMacAddress}')
insert into history (id,dt,mac,ip,comment) values (null,now(),'{ClientMacAddress}','{RequestedIpAddress}','DHCPACK/INFORM')NĂŒĂŒd rÀÀgime lĂ€hemalt silte:
Sektsioon dhcpserver kirjeldab pÔhiseadeid serveri kÀivitamiseks, nimelt:
- host â millist IP-aadressi server kuulab pordil 67
- broadcast â milline IP on DHCPOFFER ja DHCPACK jaoks broidkast
- DHCPServer â milline IP on DHCP serveril
- LeaseTime on vÀlja antud IP-aadressi rentimise aeg
- ThreadLimit â mitu samaaegset niiti on kĂ€imas UDP-pakettide töötlemiseks pordil 67. Eeldatakse, et see aitab kĂ”rgelt koormatud projektides đ
- defaultMask, defaultRouter, defaultDNS â see, mis pakutakse tellijale vaikimisi, kui IP on andmebaasis leitud, kuid tĂ€iendavad parameetrid tema jaoks pole mÀÀratud
Sektsioon mysql:
host, username, password, basename â kĂ”ik rÀÀgib enda eest. Andmebaasi ligikaudne struktuur on saadaval
Sektsioon query: siin kirjeldatakse pÀringuid OFFER/AACK saamiseks:
- offer_count â ridade arv pĂ€ringutes, mis tagastavad tulemuse kujul ip, mask, router, dns
- offer_n â pĂ€ringu rida. Kui tagastus on tĂŒhi, siis tĂ€idab jĂ€rgmise pĂ€ringu offer
- history_sql â pĂ€ring, mis kirjutab nĂ€iteks »autentimise ajaloosse« tellija kohta
PÀringutes vÔivad osaleda kÔik muutujaid sektsioonist options vÔi DHCP protokolli vÔimalused.
Sektsioon options. Siin on juba huvitavam. Siin saame luua muutujaid, mida saame hiljem kasutada sektsioonis query.
NĂ€iteks:
option_82_hex:sw_port1:20:22, see command line to take the entire line received in the DHCP request option 82, in hex format, in the range from bytes 20 to 22 inclusive and put it into a new variable sw_port1 (the switch port from which the request came)
option_82_hex:sw_mac:26:40, define the variable sw_mac, taking hex from the range 26:40
You can see all possible options that can be used in requests by running the server with the -d key. We will see a log like this:
-- DHCPINFORM packet received on port 67, from 0025224ad764, b'x91xa5xe0xa3xa5xa9-x8fx8a', ('172.30.114.25', 68)
{'ClientMacAddress': '0025224ad764',
'ClientMacAddressByte': b'x00%"Jxd7d',
'HType': 'Ethernet',
'HostName': b'x91xa5xe0xa3xa5xa9-x8fx8a',
'ReqListDNS': True,
'ReqListDomainName': True,
'ReqListPerfowmRouterDiscover': True,
'ReqListRouter': True,
'ReqListStaticRoute': True,
'ReqListSubnetMask': True,
'ReqListVendorSpecInfo': 43,
'RequestedIpAddress': '0.0.0.0',
'Vendor': b'MSFT 5.0',
'chaddr': '0025224ad764',
'ciaddr': '172.30.128.13',
'flags': b'x00x00',
'giaddr': '172.30.114.25',
'gpoz': 308,
'hlen': 6,
'hops': 1,
'htype': 'MAC',
'magic_cookie': b'cx82Sc',
'op': 'DHCPINFORM',
'option12': 12,
'option53': 53,
'option55': 55,
'option60': 60,
'option61': 61,
'option82': 82,
'option_82_byte': b'x12x01x06x00x04x00x01x00x06x02x08x00'
b'x06x00x1eXx9exb2xad',
'option_82_hex': '12010600040001000602080006001e589eb2ad',
'option_82_len': 18,
'option_82_str': "b'x12x01x06x00x04x00x01x00x06x02x08x00x06x00x1eXx9exb2xad'",
'result': False,
'secs': 768,
'siaddr': '0.0.0.0',
'sw_mac': '001e589eb2ad',
'sw_port1': '06',
'xidbyte': b'<x89}x8c',
'xidhex': '3c897d8c',
'yiaddr': '0.0.0.0'}Therefore, we can wrap any variable in {} and it will be used in the SQL query.
We will record for the record that the client received the IP address:


Serveri kÀivitamine
.\/pydhcpdb.py -d -c config.xml
â d mode displays DEBUG output to the console
â c <filename> configuration file
Flight analysis
Now, let's go into more detail about the implementation of the server in Python. It's a pain. Python was learned 'on the fly'. Many things were done in the style of: 'wow, I got it to work somehow'. It is not optimized at all and was left in this form mainly due to a lack of experience in Python development. I will focus on the most interesting aspects of the server implementation in the 'code'.
XML configuration file parser
The standard Python module xml.dom is used. It seems simple, but during the implementation, there was a noticeable lack of good documentation and examples online using this module.
tree = minidom.parse(gconfig["config_file"])
mconfig=tree.getElementsByTagName("mysql")
for elem in 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")
for elem in 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")
for elem in qconfig:
gconfig["offer_count"]=elem.getElementsByTagName("offer_count")[0].firstChild.data
for num in range(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")
for elem in options:
node=elem.getElementsByTagName("option")
for options in node:
optionsMod.append(options.firstChild.data)Mitmekeelsus
Kuid ĂŒllatavalt on Pythonis mitmekeelsus hĂ€sti arusaadav ja lihtne.
def PacketWork(data,addr):
...
# saabunud paketi analĂŒĂŒsi ja sellele vastamise rakendamine
...
while True:
data, addr = udp_socket.recvfrom(1024) # ootame UDP paketti
thread = threading.Thread(target=PacketWork, args=(data,addr,)).start() # kui saabub, kÀivitame taustal eelnevalt mÀÀratud PacketWork funktsiooni parameetritega
while threading.active_count() > gconfig["dhcp_ThreadLimit"]:
time.sleep(1) # kui kĂ€ivitatud lĂ”imed ĂŒletavad seadistustes mÀÀratud arvu, ootame, kuni neid on vĂ€hemDHCP paketi vastuvĂ”tt/saatmine
Et UDP pakette, mis liiguvad vĂ”rkaartide kaudu, peeta kinni, tuleb âtĂ”staâ sokkel:
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,socket.IPPROTO_UDP) udp_socket.bind((gconfig["dhcp_host"],67))
, kus lipud:
- AF_INET â tĂ€hendab, et aadressi formaat on IP: port. Samuti vĂ”ib olla AF_UNIX â kus aadress mÀÀratakse faili nimega.
- SOCK_DGRAM â see, et me ei saa "toores paketti", vaid juba pĂ€rast tulemusi lĂ€bi tulemĂŒĂŒri
Paketi saatmine vÔib toimuda nii broidcastina:
udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #lĂŒlitame socketi broidcast saatmise reĆŸiimi
rz=udp_socket.sendto(packetack, (gconfig["broadcast"],68)), kui ka aadressile, "kust pakk tuli":
udp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # lĂŒlitame socketi reĆŸiimi "palju kuulajaid"
rz=udp_socket.sendto(packetack, addr), kus SOL_SOCKET tÀhendab "protokolli taset" valikute seadmiseks,
, SO_BROADCAST valik, mis ĂŒtleb, et pakett saadetakse "broidcastina"
 , SO_REUSEADDR valik, mis lĂŒlitab socketi reĆŸiimi "palju kuulajaid". Ideaalis pole see antud juhul vajalik, kuid ĂŒhel FreeBSD serveril, kus testisin, ei töötanud see kood ilma selle valikuta.
DHCP paketi analĂŒĂŒs
Siin meeldis mulle tĂ”eliselt Python. Selgub, et "karbist" annab tema abil vĂ€ga vabalt töötada baitkoodiga. See vĂ”imaldab seda vĂ€ga lihtsalt tĂ”lkida kĂŒmnendvÀÀrtusteks, stringideks ja hex-ks â st seda, mida meil tĂ”eliselt vaja on, et mĂ”ista paketi struktuuri. NĂ€iteks saab saada baitide vahemiku HEX ja lihtsalt baitidena:
res["xidhex"]=data[4:8].hex()
res["xidbyte"]=data[4:8], pakkida baitide struktuuri:
res["flags"]=pack('BB',data[10],data[11])Saada IP struktuurist:
res["ciaddr"]=socket.inet_ntoa(pack('BBBB',data[12],data[13],data[14],data[15]));Ja vastupidi:
res=res+socket.inet_pton(socket.AF_INET, gconfig["dhcp_Server"])
Sellega on kĂ”ik đ
Allikas: habr.com
