zamenjava strežnika DB2DHCP (moja vilica), original tukaj, ki ga je vedno težje sestaviti za novi OS. In ni mi všeč, da je dvojiška datoteka, ki je ni mogoče "takoj spremeniti"
pridobitev delujočega strežnika DHCP z možnostjo izbire naročnikovega naslova IP z uporabo naročnikovega maca ali kombinacije stikala mac+port (možnost 82)
pisanje drugega kolesa (Oh! to je moja najljubša dejavnost)
prejemanje komentarjev o vaši spretnosti s palico na Habrahabru (ali še bolje, povabilo) 😉
Rezultat: deluje 😉 Preizkušeno na FreeBSD in Ubuntu OS. Teoretično lahko zahtevamo, da koda deluje pod katerim koli OS, ker Zdi se, da v kodi ni posebnih vezav.
Previdno! Čaka nas še marsikaj.
Povezava do repozitorija za amaterje "dotakni se živega".
Postopek namestitve, konfiguracije in uporabe je rezultat "preučevanja strojne opreme" veliko nižji, nato pa malo teorije o protokolu DHCP. Zame. In za zgodovino 😉
Malo teorije
Kaj je DHCP
To je omrežni protokol, ki napravi omogoča, da iz strežnika DHCP ugotovi svoj naslov IP (in druge parametre, kot so prehod, DNS itd.). Paketi se izmenjujejo po protokolu UDP. Splošno načelo delovanja naprave pri zahtevanju omrežnih parametrov je naslednje:
Naprava (odjemalec) pošlje zahtevo za oddajanje UDP (DHCPDISCOVER) po celotnem omrežju z zahtevo "no, nekdo mi da naslov IP." Poleg tega običajno (vendar ne vedno) zahteva poteka iz vrat 68 (vir), cilj pa je vrata 67 (cilj). Nekatere naprave pošiljajo pakete tudi iz vrat 67. Naslov MAC odjemalske naprave je vključen v paket DHCPDISCOVER.
Vsi strežniki DHCP, ki se nahajajo v omrežju (in jih je lahko več), tvorijo ponudbo DHCPOFFER z omrežnimi nastavitvami za napravo, ki je poslala DHCPDISCOVER, in jo tudi oddajajo po omrežju. Identifikacija, komu je ta paket namenjen, temelji na naslovu MAC odjemalca, navedenem prej v zahtevi DHCPDISCOVER.
Stranka sprejme pakete s predlogi omrežnih nastavitev, izbere najbolj privlačnega (kriteriji so lahko različni, na primer čas dostave paketa, število vmesnih poti) in naredi "uradno zahtevo" DHCPREQUEST z omrežnimi nastavitvami. s strežnika DHCP, ki mu je všeč. V tem primeru gre paket na določen strežnik DHCP.
Strežnik, ki je prejel DHCPREQUEST, pošlje paket formata DHCPACK, v katerem ponovno izpiše omrežne nastavitve, namenjene temu odjemalcu.
Poleg tega obstajajo paketi DHCPINFORM, ki prihajajo od odjemalca in katerih namen je obvestiti DHCP strežnik, da je »odjemalec živ« in uporablja izdane omrežne nastavitve. V izvedbi tega strežnika so ti paketi prezrti.
Oblika paketa
Na splošno je paketni okvir Ethernet videti nekako takole:
V našem primeru bomo upoštevali samo podatke neposredno iz vsebine paketa UDP, brez glav protokola plasti OSI, in sicer strukturo DHCP:
DHCPDICOVER
Torej se postopek pridobivanja naslova IP za napravo začne tako, da odjemalec DHCP pošlje zahtevo za oddajanje iz vrat 68 na 255.255.255.255:67. V tem paketu odjemalec vključuje svoj naslov MAC in tudi, kaj točno želi prejeti od strežnika DHCP. Struktura paketa je opisana v spodnji tabeli.
Tabela strukture paketa DHCPDISCOVER
Položaj v paketu
Ime vrednosti
Primer
Uvod
Bajta
pojasnilo
1
Zahteva za zagon
1
Hex
1
Vrsta sporočila. 1 - zahteva od odjemalca do strežnika, 2 - odgovor od strežnika do odjemalca
2
Vrsta strojne opreme
1
Hex
1
Vrsta naslova strojne opreme, v tem protokolu 1 - MAC
3
Dolžina naslovov strojne opreme
6
Hex
1
Dolžina naslova MAC naprave
4
Hmelj
1
Hex
1
Število vmesnih poti
5
ID transakcije
23:cf:de:1d
Hex
4
Enolični identifikator transakcije. Ustvari odjemalec na začetku operacije zahteve
7
Pretečena sekunda
0
Hex
4
Čas v sekundah od začetka postopka pridobivanja naslova
9
Zastavice za zagon
0
Hex
2
Nekatere zastavice, ki jih je mogoče nastaviti za označevanje parametrov protokola
11
IP naslov odjemalca
0.0.0.0
Linija
4
IP naslov odjemalca (če obstaja)
15
IP naslov vaše stranke
0.0.0.0
Linija
4
Naslov IP, ki ga ponuja strežnik (če je na voljo)
19
IP naslov naslednjega strežnika
0.0.0.0
Linija
4
Naslov IP strežnika (če je znan)
23
Naslov IP posrednika
172.16.114.41
Linija
4
IP naslov posrednika (na primer stikalo)
27
MAC naslov odjemalca
14:d6:4d:a7:c9:55
Hex
6
MAC naslov pošiljatelja paketa (odjemalec)
31
Polnjenje naslova strojne opreme odjemalca
Hex
10
Rezerviran sedež. Običajno napolnjena z ničlami
41
Ime gostitelja strežnika
Linija
64
Ime strežnika DHCP. Ponavadi se ne prenaša
105
Ime zagonske datoteke
Linija
128
Ime datoteke na strežniku, ki ga ob zagonu uporabljajo postaje brez diska
235
Čarobni piškoti
63: 82: 53: 63
Hex
4
“Magična” številka, po kateri vklj. lahko ugotovite, da ta paket pripada protokolu DHCP
Možnosti DHCP. Lahko gre v poljubnem vrstnem redu
236
Številka možnosti
53
december
1
Možnost 53, ki določa vrsto paketa DHCP
Številka možnosti
50
december
1
Kateri IP naslov želi stranka prejeti?
Dolžina možnosti
4
december
1
Vrednost opcije
172.16.134.61
Linija
4
Številka možnosti
55
1
Omrežni parametri, ki jih zahteva stranka. Sestava je lahko različna
01 — Omrežna maska
03 - Prehod
06 - DNS
oc — Ime gostitelja
0f - ime omrežne domene
1c - naslov zahteve za oddajanje (oddajanje)
42 - Ime strežnika TFTP
79 - Brezrazredna statična pot
Dolžina možnosti
8
1
Vrednost opcije
01:03:06:0c:0f:1c:42:79
8
Številka možnosti
82
december
Opcija 82, ki posreduje MAC naslov repetitorske naprave in nekaj dodatnih vrednosti.
Najpogosteje so to vrata stikala, na katerem teče končni odjemalec DHCP. Ta možnost vsebuje dodatne parametre. Prvi bajt je številka “podmožnosti”, drugi je njena dolžina, nato njena vrednost.
V tem primeru so v možnosti 82 podmožnosti ugnezdene:
ID vezja agenta = 00:04:00:01:00:04, kjer sta zadnja dva bajta vrata odjemalca DHCP, iz katerih je prišla zahteva
Agent Remote ID = 00:06:c8:be:19:93:11:48 - naslov MAC naprave ponavljalnika DHCP
Dolžina možnosti
18
december
Vrednost opcije
01:06
00:04:00:01:00:04
02:08
00:06:c8:be:19:93:11:48
Hex
Konec paketa
255
december
1
255 simbolizira konec paketa
DHCPPONUDBA
Takoj ko strežnik prejme paket DHCPDISCOVER in če vidi, da lahko odjemalcu ponudi nekaj od zahtevanega, potem zanj generira odgovor - DHCPDISCOVER. Odgovor se pošlje v vrata, "od koder je prišel", z oddajanjem, ker v tem trenutku odjemalec še nima naslova IP, zato lahko paket sprejme samo, če je poslan z oddajanjem. Naročnik prepozna, da je to paket zanj, po svojem MAC naslovu znotraj paketa ter transakcijski številki, ki jo generira ob kreiranju prvega paketa.
DHCPOFFER Strukturna tabela paketov
Položaj v paketu
Ime vrednosti (pogosto)
Primer
Uvod
Bajta
pojasnilo
1
Zahteva za zagon
1
Hex
1
Vrsta sporočila. 1 - zahteva od odjemalca do strežnika, 2 - odgovor od strežnika do odjemalca
2
Vrsta strojne opreme
1
Hex
1
Vrsta naslova strojne opreme, v tem protokolu 1 - MAC
3
Dolžina naslovov strojne opreme
6
Hex
1
Dolžina naslova MAC naprave
4
Hmelj
1
Hex
1
Število vmesnih poti
5
ID transakcije
23:cf:de:1d
Hex
4
Enolični identifikator transakcije. Ustvari odjemalec na začetku operacije zahteve
7
Pretečena sekunda
0
Hex
4
Čas v sekundah od začetka postopka pridobivanja naslova
9
Zastavice za zagon
0
Hex
2
Nekatere zastavice, ki jih je mogoče nastaviti za označevanje parametrov protokola. V tem primeru 0 pomeni vrsto zahteve Unicast
11
IP naslov odjemalca
0.0.0.0
Linija
4
IP naslov odjemalca (če obstaja)
15
IP naslov vaše stranke
172.16.134.61
Linija
4
Naslov IP, ki ga ponuja strežnik (če je na voljo)
19
IP naslov naslednjega strežnika
0.0.0.0
Linija
4
Naslov IP strežnika (če je znan)
23
Naslov IP posrednika
172.16.114.41
Linija
4
IP naslov posrednika (na primer stikalo)
27
MAC naslov odjemalca
14:d6:4d:a7:c9:55
Hex
6
MAC naslov pošiljatelja paketa (odjemalec)
31
Polnjenje naslova strojne opreme odjemalca
Hex
10
Rezerviran sedež. Običajno napolnjena z ničlami
41
Ime gostitelja strežnika
Linija
64
Ime strežnika DHCP. Ponavadi se ne prenaša
105
Ime zagonske datoteke
Linija
128
Ime datoteke na strežniku, ki ga ob zagonu uporabljajo postaje brez diska
235
Čarobni piškoti
63: 82: 53: 63
Hex
4
“Magična” številka, po kateri vklj. lahko ugotovite, da ta paket pripada protokolu DHCP
Možnosti DHCP. Lahko gre v poljubnem vrstnem redu
236
Številka možnosti
53
december
1
Opcija 53, ki definira tip paketa DHCP 2 - DHCPOFFER
Dolžina možnosti
1
december
1
Vrednost opcije
2
december
1
Številka možnosti
1
december
1
Možnost, da odjemalcu DHCP ponudite omrežno masko
Dolžina možnosti
4
december
1
Vrednost opcije
255.255.224.0
Linija
4
Številka možnosti
3
december
1
Možnost, da odjemalcu DHCP ponudite privzeti prehod
Dolžina možnosti
4
december
1
Vrednost opcije
172.16.12.1
Linija
4
Številka možnosti
6
december
1
Možnost ponujanja DHCP odjemalcu DNS
Dolžina možnosti
4
december
1
Vrednost opcije
8.8.8.8
Linija
4
Številka možnosti
51
december
1
Življenjska doba izdanih omrežnih parametrov v sekundah, po kateri jih mora odjemalec DHCP znova zahtevati
Dolžina možnosti
4
december
1
Vrednost opcije
86400
december
4
Številka možnosti
82
december
1
Možnost 82 ponavlja tisto, kar je prišlo v DHCPDISCOVER
Dolžina možnosti
18
december
1
Vrednost opcije
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ek
december
18
Konec paketa
255
december
1
255 simbolizira konec paketa
DHCPREQUEST
Ko odjemalec prejme DHCPOFFER, oblikuje paket, ki zahteva omrežne parametre, ne do vseh DHCP strežnikov v omrežju, ampak le do enega določenega, katerega ponudba DHCPOFFER mu je najbolj »všeč«. Kriteriji »všeč mi je« so lahko različni in odvisni od odjemalčeve implementacije DHCP. Prejemnik zahteve je določen z naslovom MAC strežnika DHCP. Prav tako lahko odjemalec pošlje paket DHCPREQUEST brez predhodnega generiranja DHCPDISCOVER, če je bil naslov IP strežnika že prej pridobljen.
Tabela strukture paketa DHCPREQUEST
Položaj v paketu
Ime vrednosti (pogosto)
Primer
Uvod
Bajta
pojasnilo
1
Zahteva za zagon
1
Hex
1
Vrsta sporočila. 1 - zahteva od odjemalca do strežnika, 2 - odgovor od strežnika do odjemalca
2
Vrsta strojne opreme
1
Hex
1
Vrsta naslova strojne opreme, v tem protokolu 1 - MAC
3
Dolžina naslovov strojne opreme
6
Hex
1
Dolžina naslova MAC naprave
4
Hmelj
1
Hex
1
Število vmesnih poti
5
ID transakcije
23:cf:de:1d
Hex
4
Enolični identifikator transakcije. Ustvari odjemalec na začetku operacije zahteve
7
Pretečena sekunda
0
Hex
4
Čas v sekundah od začetka postopka pridobivanja naslova
9
Zastavice za zagon
8000
Hex
2
Nekatere zastavice, ki jih je mogoče nastaviti za označevanje parametrov protokola. V tem primeru je nastavljeno »oddajanje«.
11
IP naslov odjemalca
0.0.0.0
Linija
4
IP naslov odjemalca (če obstaja)
15
IP naslov vaše stranke
172.16.134.61
Linija
4
Naslov IP, ki ga ponuja strežnik (če je na voljo)
19
IP naslov naslednjega strežnika
0.0.0.0
Linija
4
Naslov IP strežnika (če je znan)
23
Naslov IP posrednika
172.16.114.41
Linija
4
IP naslov posrednika (na primer stikalo)
27
MAC naslov odjemalca
14:d6:4d:a7:c9:55
Hex
6
MAC naslov pošiljatelja paketa (odjemalec)
31
Polnjenje naslova strojne opreme odjemalca
Hex
10
Rezerviran sedež. Običajno napolnjena z ničlami
41
Ime gostitelja strežnika
Linija
64
Ime strežnika DHCP. Ponavadi se ne prenaša
105
Ime zagonske datoteke
Linija
128
Ime datoteke na strežniku, ki ga ob zagonu uporabljajo postaje brez diska
235
Čarobni piškoti
63: 82: 53: 63
Hex
4
“Magična” številka, po kateri vklj. lahko ugotovite, da ta paket pripada protokolu DHCP
Možnosti DHCP. Lahko gre v poljubnem vrstnem redu
236
Številka možnosti
53
december
3
Opcija 53, ki definira DHCP paket tipa 3 - DHCPREQUEST
Dolžina možnosti
1
december
1
Vrednost opcije
3
december
1
Številka možnosti
61
december
1
ID odjemalca: 01 (za Ehernet) + naslov MAC odjemalca
Dolžina možnosti
7
december
1
Vrednost opcije
01:2c:ab:25:ff:72:a6
Hex
7
Številka možnosti
60
december
"Identifikator razreda prodajalca". V mojem primeru sporoči različico odjemalca DHCP. Morda druge naprave vrnejo nekaj drugega. Windows na primer poroča o MSFT 5.0
Dolžina možnosti
11
december
Vrednost opcije
udhcp 0.9.8
Linija
Številka možnosti
55
1
Omrežni parametri, ki jih zahteva stranka. Sestava je lahko različna
01 — Omrežna maska
03 - Prehod
06 - DNS
oc — Ime gostitelja
0f - ime omrežne domene
1c - naslov zahteve za oddajanje (oddajanje)
42 - Ime strežnika TFTP
79 - Brezrazredna statična pot
Dolžina možnosti
8
1
Vrednost opcije
01:03:06:0c:0f:1c:42:79
8
Številka možnosti
82
december
1
Možnost 82 ponavlja tisto, kar je prišlo v DHCPDISCOVER
Dolžina možnosti
18
december
1
Vrednost opcije
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ek
december
18
Konec paketa
255
december
1
255 simbolizira konec paketa
DHCPACK
Kot potrditev, da "ja, tako je, to je vaš IP naslov in ne bom ga izdal nikomur drugemu" s strežnika DHCP služi paket v formatu DHCPACK od strežnika do odjemalca. Pošilja se v oddaji tako kot drugi paketi. Čeprav v spodnji kodi za strežnik DHCP, implementiran v Pythonu, za vsak slučaj podvojim vsako zahtevo za oddajanje tako, da pošljem paket na določen IP odjemalca, če je že znan. Poleg tega strežnika DHCP sploh ne zanima, ali je paket DHCPACK dosegel odjemalca. Če odjemalec ne prejme DHCPACK, čez nekaj časa preprosto ponovi DHCPREQUEST
Tabela strukture paketa DHCPACK
Položaj v paketu
Ime vrednosti (pogosto)
Primer
Uvod
Bajta
pojasnilo
1
Zahteva za zagon
2
Hex
1
Vrsta sporočila. 1 - zahteva od odjemalca do strežnika, 2 - odgovor od strežnika do odjemalca
2
Vrsta strojne opreme
1
Hex
1
Vrsta naslova strojne opreme, v tem protokolu 1 - MAC
3
Dolžina naslovov strojne opreme
6
Hex
1
Dolžina naslova MAC naprave
4
Hmelj
1
Hex
1
Število vmesnih poti
5
ID transakcije
23:cf:de:1d
Hex
4
Enolični identifikator transakcije. Ustvari odjemalec na začetku operacije zahteve
7
Pretečena sekunda
0
Hex
4
Čas v sekundah od začetka postopka pridobivanja naslova
9
Zastavice za zagon
8000
Hex
2
Nekatere zastavice, ki jih je mogoče nastaviti za označevanje parametrov protokola. V tem primeru je nastavljeno »oddajanje«.
11
IP naslov odjemalca
0.0.0.0
Linija
4
IP naslov odjemalca (če obstaja)
15
IP naslov vaše stranke
172.16.134.61
Linija
4
Naslov IP, ki ga ponuja strežnik (če je na voljo)
19
IP naslov naslednjega strežnika
0.0.0.0
Linija
4
Naslov IP strežnika (če je znan)
23
Naslov IP posrednika
172.16.114.41
Linija
4
IP naslov posrednika (na primer stikalo)
27
MAC naslov odjemalca
14:d6:4d:a7:c9:55
Hex
6
MAC naslov pošiljatelja paketa (odjemalec)
31
Polnjenje naslova strojne opreme odjemalca
Hex
10
Rezerviran sedež. Običajno napolnjena z ničlami
41
Ime gostitelja strežnika
Linija
64
Ime strežnika DHCP. Ponavadi se ne prenaša
105
Ime zagonske datoteke
Linija
128
Ime datoteke na strežniku, ki ga ob zagonu uporabljajo postaje brez diska
235
Čarobni piškoti
63: 82: 53: 63
Hex
4
“Magična” številka, po kateri vklj. lahko ugotovite, da ta paket pripada protokolu DHCP
Možnosti DHCP. Lahko gre v poljubnem vrstnem redu
236
Številka možnosti
53
december
3
Opcija 53, ki definira DHCP paket tipa 5 - DHCPACK
Dolžina možnosti
1
december
1
Vrednost opcije
5
december
1
Številka možnosti
1
december
1
Možnost, da odjemalcu DHCP ponudite omrežno masko
Dolžina možnosti
4
december
1
Vrednost opcije
255.255.224.0
Linija
4
Številka možnosti
3
december
1
Možnost, da odjemalcu DHCP ponudite privzeti prehod
Dolžina možnosti
4
december
1
Vrednost opcije
172.16.12.1
Linija
4
Številka možnosti
6
december
1
Možnost ponujanja DHCP odjemalcu DNS
Dolžina možnosti
4
december
1
Vrednost opcije
8.8.8.8
Linija
4
Številka možnosti
51
december
1
Življenjska doba izdanih omrežnih parametrov v sekundah, po kateri jih mora odjemalec DHCP znova zahtevati
Dolžina možnosti
4
december
1
Vrednost opcije
86400
december
4
Številka možnosti
82
december
1
Možnost 82 ponavlja tisto, kar je prišlo v DHCPDISCOVER
Dolžina možnosti
18
december
1
Vrednost opcije
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ek
december
18
Konec paketa
255
december
1
255 simbolizira konec paketa
Namestitev
Namestitev je pravzaprav sestavljena iz namestitve modulov python, potrebnih za delo. Predpostavlja se, da je MySQL že nameščen in konfiguriran.
Ustvarimo bazo podatkov MySQL, vanjo naložimo dump pydhcp.sql in konfiguriramo konfiguracijsko datoteko.
Konfiguracija
Vse nastavitve strežnika so v datoteki xml. Referenčna datoteka:
1.0 0.0.0.0 255.255.255.255 192.168.0.71 8600 1 255.255.255.0 192.168.0.1 lokalni gostitelj test test pydhcp možnost_8.8.8.8_hex:sw_vrata82:1:20 možnost_22_hex:sw_port82:2:16 možnost_18_hex:sw_mac:82:26 40 izberite ip,mask,router,dns od uporabnikov, kjer je upper(mac)=upper('{option_3_AgentRemoteId_hex}') in upper(port)=upper('{option_1_AgentCircuitId_port_hex}') izberite ip,mask,router,dns od uporabnikov, kjer je upper(mac)=upper('{sw_mac}') in upper(port)=upper('{sw_port82}') izberite ip,mask,router,dns od uporabnikov, kjer je upper(mac)=upper('{ClientMacAddress}') vstavi v zgodovino (id,dt,mac,ip,comment) vrednosti (null,now(),'{ClientMacAddress}','{RequestedIpAddress}','DHCPACK/INFORM')
Zdaj pa podrobneje o oznakah:
V razdelku dhcpserver so opisane osnovne nastavitve za zagon strežnika, in sicer:
gostitelj - kateri naslov IP strežnik posluša na vratih 67
oddajanje - kateri ip je oddajanje za DHCPOFFER in DHCPACK
DHCPServer - kakšen je ip strežnika DHCP
LeaseTime čas zakupa izdanega naslova IP
ThreadLimit - koliko niti se hkrati izvaja za obdelavo dohodnih paketov UDP na vratih 67. Pomagal naj bi pri visoko obremenjenih projektih 😉
defaultMask,defaultRouter,defaultDNS - kaj je privzeto ponujeno naročniku, če je IP najden v bazi podatkov, vendar zanj niso določeni dodatni parametri
razdelek mysql:
gostitelj, uporabniško ime, geslo, osnovno ime - vse govori samo zase. Približna struktura baze podatkov je objavljena na GitHub
Razdelek za poizvedbe: zahteve za prejem PONUDBE/ACK so opisane tukaj:
offer_count — število vrstic z zahtevami, ki vrnejo rezultat, kot je ip,mask,router,dns
offer_n — poizvedbeni niz. Če je vrnitev prazna, izvede naslednjo zahtevo za ponudbo
history_sql - poizvedba, ki piše na primer v "zgodovino avtorizacije" za naročnika
Zahteve lahko vključujejo poljubne spremenljivke iz razdelka z možnostmi ali možnosti iz protokola DHCP.
Razdelek z možnostmi. Tukaj postane bolj zanimivo. Tukaj lahko ustvarimo spremenljivke, ki jih lahko kasneje uporabimo v razdelku poizvedbe.
Na primer:
option_82_hex:sw_port1:20:22
, ta ukazna vrstica prevzame celotno vrstico, ki je prišla v možnosti zahteve DHCP 82, v šestnajstiškem formatu, v obsegu od 20 do vključno 22 bajtov, in jo postavi v novo spremenljivko sw_port1 (preklopna vrata, od koder je prišla zahteva)
option_82_hex:sw_mac:26:40
, definirajte spremenljivko sw_mac, pri čemer vzamete hex iz obsega 26:40
Vse možne možnosti, ki jih je mogoče uporabiti v poizvedbah, si lahko ogledate tako, da zaženete strežnik s stikalom -d. Videli bomo nekaj podobnega temu dnevniku:
V skladu s tem lahko katero koli spremenljivko zavijemo v {} in ta bo uporabljena v poizvedbi SQL.
Zabeležimo v zgodovino, da je stranka prejela naslov IP:
Zagon strežnika
./pydhcpdb.py -d -c config.xml
— d konzolni izhodni način DEBUG
- c <ime datoteke> konfiguracijska datoteka
Povzetek
In zdaj več podrobnosti o implementaciji strežnika v Python. To je bolečina. Pythona so se učili sproti. Veliko trenutkov je narejenih v slogu "vau, nekako mi je uspelo." Sploh ni optimiziran in ostal v tej obliki predvsem zaradi malo izkušenj z razvojem Pythona. O najbolj zanimivih vidikih implementacije strežnika se bom ustavil v "kodi".
Razčlenjevalnik konfiguracijske datoteke XML
Uporabljen je standardni modul Python xml.dom. Zdi se preprosto, vendar je bilo med izvajanjem opazno pomanjkanje jasne dokumentacije in primerov v omrežju, ki uporablja ta modul.
drevo = minidom.parse(gconfig["config_file"]) mconfig=tree.getElementsByTagName("mysql") za elem v mconfig: gconfig["mysql_host"]=elem.getElementsByTagName("host")[0].firstChild.data gconfig["mysql_username"]=elem.getElementsByTagName("uporabniško ime")[0].firstChild.data gconfig["mysql_password"]=elem.getElementsByTagName("geslo")[0].firstChild.data gconfig["mysql_basename"] =elem.getElementsByTagName("basename")[0].firstChild.data dconfig=tree.getElementsByTagName("dhcpserver") za elem v 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") za elem v qconfig: gconfig["offer_count"]=elem.getElementsByTagName("offer_count")[0].firstChild.data za num v obseg(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") za elem v možnostih: node=elem.getElementsByTagName("option") za možnosti v vozlišču : optionsMod.append(options.firstChild.data)
Večnitnost
Nenavadno je, da je večnitnost v Pythonu implementirana zelo jasno in preprosto.
def PacketWork(data,addr): ... # implementacija razčlenjevanja dohodnega paketa in odziva nanj ... while True: data, addr = udp_socket.recvfrom(1024) # čakanje na paket UDP thread = threading.Thread( target=PacketWork , args=(data,addr,)).start() # kot je prišlo - zaženemo predhodno definirano funkcijo PacketWork v ozadju s parametri med threading.active_count() >gconfig["dhcp_ThreadLimit"]: čas. sleep(1) # če je število Teče več niti kot v nastavitvah, počakamo, da jih je manj
Sprejmi/pošlji paket DHCP
Če želite prestreči pakete UDP, ki prihajajo skozi omrežno kartico, morate "dvigniti" vtičnico:
AF_INET - pomeni, da bo oblika naslova IP: vrata. Obstaja lahko tudi AF_UNIX - kjer je naslov podan z imenom datoteke.
SOCK_DGRAM - pomeni, da ne sprejmemo “surovega paketa”, ampak tistega, ki je že šel skozi požarni zid, in z delno obrezanim paketom. Tisti. prejmemo le paket UDP brez "fizične" komponente ovoja paketa UDP. Če uporabljate zastavico SOCK_RAW, boste morali razčleniti tudi ta »ovitek«.
Pošiljanje paketa je lahko kot oddaja:
udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #preklop vtičnice na način oddajanja rz=udp_socket.sendto(packetack, (gconfig["broadcast"],68))
, in na naslov "od kod prihaja paket":
udp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # preklop vtičnice v način več poslušalcev rz=udp_socket.sendto(packetack, addr)
, pri čemer SOL_SOCKET pomeni "nivo protokola" za možnosti nastavitve,
, možnost SO_BROADCAST, da je paket čelade »oddajanje«
,SO_REUSEADDR možnost preklopi vtičnico v način "več poslušalcev". Teoretično je v tem primeru nepotreben, a na enem od strežnikov FreeBSD, na katerem sem testiral, koda brez te možnosti ni delovala.
Razčlenjevanje paketa DHCP
Tukaj mi je bil Python zelo všeč. Izkazalo se je, da takoj po namestitvi omogoča, da ste precej prilagodljivi z bajtno kodo. Omogoča zelo enostavno prevajanje v decimalne vrednosti, nize in šestnajstiške - tj. to je tisto, kar dejansko potrebujemo, da razumemo strukturo paketa. Tako lahko na primer dobite obseg bajtov v HEX in samo bajte: