замена сервера ДБ2ДХЦП (моја виљушка), оригинал овде, који постаје све теже саставити за нови ОС. И не свиђа ми се што је то бинарност коју нема начина да се „промени одмах“
добијање функционалног ДХЦП сервера са могућношћу одабира ИП адресе претплатника користећи претплатников мац или комбинацију мац+порт (опција 82)
писање другог бицикла (Ох! ово је моја омиљена активност)
примате коментаре о вашем клупском понашању на Хабрахабру (или још боље, позивницу) 😉
Резултат: ради 😉 Тестирано на ФрееБСД и Убунту ОС. Теоретски, код се може тражити да ради под било којим ОС-ом, јер Чини се да у коду нема посебних веза.
Пажљиво! Има још много тога.
Линк ка репозиторијуму за аматере "додирни жив".
Процес инсталирања, конфигурисања и коришћења резултат „проучавања хардвера“ је много нижи, а затим и мало теорије о ДХЦП протоколу. За мене. И за историју 😉
Мало теорије
Шта је ДХЦП
Ово је мрежни протокол који омогућава уређају да сазна своју ИП адресу (и друге параметре као што су гатеваи, ДНС, итд.) са ДХЦП сервера. Пакети се размењују коришћењем УДП протокола. Општи принцип рада уређаја при тражењу мрежних параметара је следећи:
Уређај (клијент) шаље УДП захтев за емитовање (ДХЦПДИСЦОВЕР) широм мреже са захтевом „па, неко ми да ИП адресу“. Штавише, обично (али не увек) захтев се јавља са порта 68 (извор), а одредиште је порт 67 (одредиште). Неки уређаји такође шаљу пакете са порта 67. МАЦ адреса клијентског уређаја је укључена у ДХЦПДИСЦОВЕР пакет.
Сви ДХЦП сервери који се налазе на мрежи (а може их бити неколико) формирају ДХЦПОФФЕР понуду са мрежним подешавањима за уређај који је послао ДХЦПДИСЦОВЕР, а такође га емитују преко мреже. Идентификација коме је овај пакет намењен заснива се на МАЦ адреси клијента датој раније у ДХЦПДИСЦОВЕР захтеву.
Клијент прихвата пакете са предлозима мрежних подешавања, бира најатрактивнији (критеријуми могу бити различити, на пример, време испоруке пакета, број међурута) и поставља „званични захтев“ ДХЦПРЕКУЕСТ са мрежним подешавањима са ДХЦП сервера који воли. У овом случају, пакет иде на одређени ДХЦП сервер.
Сервер који је примио ДХЦПРЕКУЕСТ шаље пакет у формату ДХЦПАЦК, у којем још једном наводи мрежна подешавања намењена овом клијенту
Поред тога, постоје ДХЦПИНФОРМ пакети који долазе од клијента, а чија је сврха да обавесте ДХЦП сервер да је „клијент жив“ и да користи издата мрежна подешавања. У имплементацији овог сервера, ови пакети се игноришу.
У нашем случају, разматраћемо само податке директно из садржаја УДП пакета, без заглавља протокола ОСИ слоја, односно ДХЦП структуру:
ДХЦПДИСЦОВЕР
Дакле, процес добијања ИП адресе за уређај почиње тако што ДХЦП клијент шаље захтев за емитовање са порта 68 на 255.255.255.255:67. У овај пакет клијент укључује своју МАЦ адресу, као и шта тачно жели да добије од ДХЦП сервера. Структура пакета је описана у табели испод.
ДХЦПДИСЦОВЕР табела структуре пакета
Положај у пакету
Име вредности
Пример
Увод
Бајт
Разјашњење
1
Захтев за покретање
1
Хек
1
Врста поруке. 1 - захтев од клијента до сервера, 2 - одговор од сервера до клијента
2
Тип хардвера
1
Хек
1
Тип хардверске адресе, у овом протоколу 1 - МАЦ
3
Дужина хардверске адресе
6
Хек
1
Дужина МАЦ адресе уређаја
4
Хмељ
1
Хек
1
Број међупутева
5
ИД трансакције
23:цф:де:1д
Хек
4
Јединствени идентификатор трансакције. Генерисано од стране клијента на почетку операције захтева
7
Сецонд елапсед
0
Хек
4
Време у секундама од почетка процеса добијања адресе
9
Боот флагс
0
Хек
2
Одређене заставице које се могу подесити да указују на параметре протокола
Број опције
50
дец
1
Коју ИП адресу клијент жели да прими?
Опциона дужина
4
дец
1
Вредност опције
172.16.134.61
Линија
4
Број опције
55
1
Мрежни параметри које захтева клијент. Састав се може разликовати
01 — Мрежна маска
03 - Гатеваи
06 - ДНС
оц — Име хоста
0ф - име мрежног домена
1ц - адреса захтева за емитовање (емитовање)
42 - Име ТФТП сервера
79 - Безкласна статичка рута
Опциона дужина
8
1
Вредност опције
01:03:06:0c:0f:1c:42:79
8
Број опције
82
дец
Опција 82, која преноси МАЦ адресу репетиторног уређаја и неке додатне вредности.
Најчешће је то порт прекидача на коме се покреће крајњи ДХЦП клијент.Ова опција садржи додатне параметре.Први бајт је број „подопције“, други је њена дужина, затим њена вредност.
У овом случају, у опцији 82, подопције су угнежђене:
ИД круга агента = 00:04:00:01:00:04, где су последња два бајта ДХЦП порт клијента са којег је стигао захтев
Вредност опције
01:06
00:04:00:01:00:04
02:08
00:06:c8:be:19:93:11:48
Хек
Крај пакета
255
дец
1
255 симболизује крај пакета
ДХЦПОФФЕР
Чим сервер прими ДХЦПДИСЦОВЕР пакет и ако види да може понудити клијенту нешто од траженог, онда за њега генерише одговор - ДХЦПДИСЦОВЕР. Одговор се шаље порту „одакле је дошао“, емитовањем, јер у овом тренутку, клијент још увек нема ИП адресу, стога може прихватити пакет само ако је послат путем емитовања. Клијент препознаје да је ово пакет за њега по својој МАЦ адреси унутар пакета, као и по броју трансакције који генерише у тренутку креирања првог пакета.
ДХЦПОФФЕР табела структуре пакета
Положај у пакету
Назив вредности (уобичајено)
Пример
Увод
Бајт
Разјашњење
1
Захтев за покретање
1
Хек
1
Врста поруке. 1 - захтев од клијента до сервера, 2 - одговор од сервера до клијента
2
Тип хардвера
1
Хек
1
Тип хардверске адресе, у овом протоколу 1 - МАЦ
3
Дужина хардверске адресе
6
Хек
1
Дужина МАЦ адресе уређаја
4
Хмељ
1
Хек
1
Број међупутева
5
ИД трансакције
23:цф:де:1д
Хек
4
Јединствени идентификатор трансакције. Генерисано од стране клијента на почетку операције захтева
7
Сецонд елапсед
0
Хек
4
Време у секундама од почетка процеса добијања адресе
9
Боот флагс
0
Хек
2
Одређене заставице које се могу подесити да указују на параметре протокола. У овом случају, 0 значи Уницаст тип захтева
Хек
10
Резервисано место. Обично је испуњен нулама
41
Име сервера хоста
Линија
64
Име ДХЦП сервера. Обично се не преноси
105
Име датотеке за покретање
Линија
128
Име датотеке на серверу који користе станице без диска при покретању
235
Магични колачићи
КСНУМКС: КСНУМКС: КСНУМКС: КСНУМКС
Хек
4
„Магични“ број, према којем, укљ. можете утврдити да овај пакет припада ДХЦП протоколу
ДХЦП опције. Може ићи било којим редоследом
236
Број опције
53
дец
1
Опција 53, која дефинише тип ДХЦП 2 пакета - ДХЦПОФФЕР
Опциона дужина
1
дец
1
Вредност опције
2
дец
1
Број опције
1
дец
1
Опција да се ДХЦП клијенту понуди мрежна маска
Опциона дужина
4
дец
1
Вредност опције
255.255.224.0
Линија
4
Број опције
3
дец
1
Опција да се ДХЦП клијенту понуди подразумевани гатеваи
Опциона дужина
4
дец
1
Вредност опције
172.16.12.1
Линија
4
Број опције
6
дец
1
Опција да понудите ДХЦП ДНС клијенту
Опциона дужина
4
дец
1
Вредност опције
8.8.8.8
Линија
4
Број опције
51
дец
1
Животни век издатих мрежних параметара у секундама, након чега ДХЦП клијент мора поново да их захтева
Опциона дужина
4
дец
1
Вредност опције
86400
дец
4
Број опције
82
дец
1
Опција 82, понавља оно што је стигло у ДХЦПДИСЦОВЕР-у
Опциона дужина
18
дец
1
Вредност опције
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4д:ец
дец
18
Крај пакета
255
дец
1
255 симболизује крај пакета
ДХЦПРЕКУЕСТ
Након што клијент прими ДХЦПОФФЕР, он формира пакет који захтева мрежне параметре не свим ДХЦП серверима на мрежи, већ само једном одређеном, чија му се ДХЦПОФФЕР понуда највише „свиђа”. Критеријуми „свиђања“ могу бити различити и зависе од имплементације ДХЦП клијента. Прималац захтева се наводи коришћењем МАЦ адресе ДХЦП сервера. Такође, ДХЦПРЕКУЕСТ пакет може послати клијент без претходног генерисања ДХЦПДИСЦОВЕР-а, ако је ИП адреса сервера већ раније добијена.
ДХЦПРЕКУЕСТ табела структуре пакета
Положај у пакету
Назив вредности (уобичајено)
Пример
Увод
Бајт
Разјашњење
1
Захтев за покретање
1
Хек
1
Врста поруке. 1 - захтев од клијента до сервера, 2 - одговор од сервера до клијента
2
Тип хардвера
1
Хек
1
Тип хардверске адресе, у овом протоколу 1 - МАЦ
3
Дужина хардверске адресе
6
Хек
1
Дужина МАЦ адресе уређаја
4
Хмељ
1
Хек
1
Број међупутева
5
ИД трансакције
23:цф:де:1д
Хек
4
Јединствени идентификатор трансакције. Генерисано од стране клијента на почетку операције захтева
7
Сецонд елапсед
0
Хек
4
Време у секундама од почетка процеса добијања адресе
9
Боот флагс
8000
Хек
2
Одређене заставице које се могу подесити да указују на параметре протокола. У овом случају је подешено „емитовање“.
Хек
10
Резервисано место. Обично је испуњен нулама
41
Име сервера хоста
Линија
64
Име ДХЦП сервера. Обично се не преноси
105
Име датотеке за покретање
Линија
128
Име датотеке на серверу који користе станице без диска при покретању
235
Магични колачићи
КСНУМКС: КСНУМКС: КСНУМКС: КСНУМКС
Хек
4
„Магични“ број, према којем, укљ. можете утврдити да овај пакет припада ДХЦП протоколу
ДХЦП опције. Може ићи било којим редоследом
236
Број опције
53
дец
3
Опција 53, која дефинише тип ДХЦП пакета 3 - ДХЦПРЕКУЕСТ
Опциона дужина
1
дец
1
Вредност опције
3
дец
1
Број опције
61
дец
1
ИД клијента: 01 (за Ехернет) + МАЦ адреса клијента
Опциона дужина
7
дец
1
Вредност опције
01:2c:ab:25:ff:72:a6
Хек
7
Број опције
60
дец
„Идентификатор класе добављача“. У мом случају, пријављује верзију ДХЦП клијента. Можда други уређаји враћају нешто другачије. Виндовс, на пример, извештава о МСФТ 5.0
Опциона дужина
11
дец
Вредност опције
удхцп 0.9.8
Линија
Број опције
55
1
Мрежни параметри које захтева клијент. Састав се може разликовати
01 — Мрежна маска
03 - Гатеваи
06 - ДНС
оц — Име хоста
0ф - име мрежног домена
1ц - адреса захтева за емитовање (емитовање)
42 - Име ТФТП сервера
79 - Безкласна статичка рута
Опциона дужина
8
1
Вредност опције
01:03:06:0c:0f:1c:42:79
8
Број опције
82
дец
1
Опција 82, понавља оно што је стигло у ДХЦПДИСЦОВЕР-у
Опциона дужина
18
дец
1
Вредност опције
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4д:ец
дец
18
Крај пакета
255
дец
1
255 симболизује крај пакета
ДХЦПАЦК
Као потврду „да, тако је, ово је ваша ИП адреса и нећу је дати никоме другом“ са ДХЦП сервера, пакет у ДХЦПАЦК формату од сервера до клијента служи. Шаље се као и други пакети. Мада, у коду испод за ДХЦП сервер имплементиран у Питхон-у, за сваки случај, дуплирам било који захтев за емитовање тако што шаљем пакет на одређени ИП клијента, ако је већ познат. Штавише, ДХЦП сервер уопште не брине да ли је ДХЦПАЦК пакет стигао до клијента. Ако клијент не прими ДХЦПАЦК, онда након неког времена једноставно понавља ДХЦПРЕКУЕСТ
Табела структуре ДХЦПАЦК пакета
Положај у пакету
Назив вредности (уобичајено)
Пример
Увод
Бајт
Разјашњење
1
Захтев за покретање
2
Хек
1
Врста поруке. 1 - захтев од клијента до сервера, 2 - одговор од сервера до клијента
2
Тип хардвера
1
Хек
1
Тип хардверске адресе, у овом протоколу 1 - МАЦ
3
Дужина хардверске адресе
6
Хек
1
Дужина МАЦ адресе уређаја
4
Хмељ
1
Хек
1
Број међупутева
5
ИД трансакције
23:цф:де:1д
Хек
4
Јединствени идентификатор трансакције. Генерисано од стране клијента на почетку операције захтева
7
Сецонд елапсед
0
Хек
4
Време у секундама од почетка процеса добијања адресе
9
Боот флагс
8000
Хек
2
Одређене заставице које се могу подесити да указују на параметре протокола. У овом случају је подешено „емитовање“.
Креирамо МиСКЛ базу података, отпремамо пидхцп.скл думп у њу и конфигуришемо конфигурациону датотеку.
Конфигурација
Сва подешавања сервера су у кмл датотеци. Референтни фајл:
1.0 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_хек:св_порт82:1:20 оптион_22_хек:св_порт82:2:16 оптион_18_хек:св_мац:82:26 40 изаберите ип,маск,рутер,днс од корисника где је уппер(мац)=уппер('{оптион_3_АгентРемотеИд_хек}') и уппер(порт)=уппер('{оптион_1_АгентЦирцуитИд_порт_хек}') изаберите ип,маск,рутер,днс од корисника где је уппер(мац)=уппер('{св_мац}') и уппер(порт)=уппер('{св_порт82}') изаберите ип,маск,рутер,днс од корисника где је уппер(мац)=уппер('{ЦлиентМацАддресс}') убаци у историју (ид,дт,мац,ип,цоммент) вредности (нулл,нов(),'{ЦлиентМацАддресс}','{РекуестедИпАддресс}','ДХЦПАЦК/ИНФОРМ')
Сада детаљније о ознакама:
Одељак дхцпсервер описује основна подешавања за покретање сервера, и то:
хост - коју ИП адресу сервер слуша на порту 67
броадцаст - који ИП је емитовање за ДХЦПОФФЕР и ДХЦПАЦК
ДХЦПСервер - који је ип ДХЦП сервера
ЛеасеТиме време закупа издате ИП адресе
ТхреадЛимит – колико нити се покреће истовремено за обраду долазних УДП пакета на порту 67. Требало би да помогне у пројектима са великим оптерећењем 😉
дефаултМаск,дефаултРоутер,дефаултДНС - шта се подразумевано нуди претплатнику ако је ИП пронађен у бази података, али за њега нису наведени додатни параметри
мискл одељак:
хост, корисничко име, лозинка, основно име - све говори само за себе. Приближна структура базе података је објављена на ГитХуб
Одељак за упите: овде су описани захтеви за пријем ПОНУДЕ/АЦК:
оффер_цоунт — број редова са захтевима који враћају резултат као што су ип, маска, рутер, днс
понуда_н — стринг упита. Ако је ретурн празан, извршава се следећи захтев за понуду
хистори_скл - упит који уписује, на пример, у „историју ауторизације“ за претплатника
Захтеви могу укључивати било које променљиве из одељка са опцијама или опције из ДХЦП протокола.
Одељак са опцијама. Овде постаје занимљивије. Овде можемо да креирамо променљиве које можемо користити касније у одељку за упите.
На пример:
option_82_hex:sw_port1:20:22
, ова командна линија преузима цео ред који је дошао у опцији ДХЦП захтева 82, у хексадецималном формату, у опсегу од 20 до 22 бајта укључујући и ставља га у нову променљиву св_порт1 (промени порт одакле је захтев стигао)
option_82_hex:sw_mac:26:40
, дефинише променљиву св_мац, узимајући хексадецимални из опсега 26:40
Можете видети све могуће опције које се могу користити у упитима покретањем сервера са -д прекидачем. Видећемо нешто попут овог дневника:
А сада више детаља о имплементацији сервера у Питхон-у. То је бол. Пајтон је научен у ходу. Многи тренуци су направљени у стилу „вау, некако сам успео“. Уопште није оптимизован и остављен у овом облику углавном због малог искуства у развоју Питхон-а. Задржаћу се на најзанимљивијим аспектима имплементације сервера у „коду“.
Парсер КСМЛ конфигурационих датотека
Користи се стандардни Питхон модул кмл.дом. Делује једноставно, али током имплементације приметан је недостатак јасне документације и примера на мрежи користећи овај модул.
трее = минидом.парсе(гцонфиг["цонфиг_филе"]) мцонфиг=трее.гетЕлементсБиТагНаме("мискл") за елем у мцонфиг: гцонфиг["мискл_хост"]=елем.гетЕлементсБиТагНаме("хост")хида. гцонфиг["мискл_усернаме"]=елем.гетЕлементсБиТагНаме("усернаме")[0].фирстЦхилд.дата гцонфиг["мискл_пассворд"]=елем.гетЕлементсБиТагНаме("пассворд")[0].фирстЦхилд.цонфиг.дамис гцонфиг["мискл_пассворд"]=елем.гетЕлементсБиТагНаме("пассворд")[0].фирстЦхилд. =елем.гетЕлементсБиТагНаме("басенаме")[0].фирстЦхилд.дата дцонфиг=трее.гетЕлементсБиТагНаме("дхцпсервер") за елем у дцонфиг: гцонфиг["броадцаст"]=елем.гетЕлементсБиТагНаме")[0]. фирстЦхилд.дата гцонфиг["дхцп_хост"]=елем.гетЕлементсБиТагНаме("хост")[0].фирстЦхилд.дата гцонфиг["дхцп_ЛеасеТиме"]=елем.гетЕлементсБиТагНаме("ЛеасеТиме")[д.да"гцонфиг[0].фирстЦхи[0].фирстЦхи[0]. дхцп_ТхреадЛимит"]=инт(елем.гетЕлементсБиТагНаме("ТхреадЛимит")[0].фирстЦхилд.дата) гцонфиг["дхцп_Сервер"]=елем.гетЕлементсБиТагНаме("ДХЦПСервер")[да]фирстЦхилдск_де. = елемелелементсбитагнаме ("дефаултмаск") [0] .фирстцхилд.дата гцонфиг ["дхцп_дефаулттроутер"] = елемелелементсбитагнаме ("дефраутер") [0] .фирстцхилд.дата гцонфиг ["ДХЦП_ДЕФАУЛТДНС"] = елем.гетелементсбитагнаме (" дефаултДНС")[0].фирстЦхилд.дата кцонфиг=трее.гетЕлементсБиТагНаме("куери") за елем у кцонфиг: гцонфиг["оффер_цоунт"]=елем.гетЕлементсБиТагНаме("оффер_цоунт")[1].фирстЦхилд ин.дата за елем. опсег(инт(гцонфиг["оффер_цоунт"])): гцонфиг["оффер_"+стр(нум+1)]=елем.гетЕлементсБиТагНаме("оффер_"+стр(нум+0))[0].фирстЦхилд.дата гцонфиг ["хистори_скл"]=елем.гетЕлементсБиТагНаме("хистори_скл")[XNUMX].фирстЦхилд.дата оптионс=трее.гетЕлементсБиТагНаме("оптионс") за елем у опцијама: ноде=елем.гетЕлементсБиТагНаме("ин ноде") за опције : оптионсМод.аппенд(оптионс.фирстЦхилд.дата)
Мултитхреадинг
Чудно је да се вишенитност у Питхон-у имплементира веома јасно и једноставно.
деф ПацкетВорк(дата,аддр): ... # имплементација рашчлањивања долазног пакета и одговора на њега ... док је Труе: дата, аддр = удп_соцкет.рецвфром(1024) # чека се нит УДП пакета = тхреадинг.Тхреад( таргет=ПацкетВорк , аргс=(дата,аддр,)).старт() # како је дошло - покрећемо претходно дефинисану ПацкетВорк функцију у позадини са параметрима док тхреадинг.ацтиве_цоунт() >гцонфиг["дхцп_ТхреадЛимит"]: време. слееп(1) # ако је број Већ покренутих више нити него у подешавањима, чекамо док их не буде мање
Примите/пошаљите ДХЦП пакет
Да бисте пресрели УДП пакете који долазе преко мрежне картице, потребно је да „подигнете“ сокет:
АФ_ИНЕТ - значи да ће формат адресе бити ИП: порт. Такође може постојати АФ_УНИКС - где је адреса дата именом датотеке.
СОЦК_ДГРАМ - значи да не прихватамо „сирови пакет“, већ онај који је већ прошао кроз заштитни зид, и то са делимично скраћеним пакетом. Оне. примамо само УДП пакет без „физичке“ компоненте омотача УДП пакета. Ако користите СОЦК_РАВ заставицу, онда ћете такође морати да рашчланите овај „омот“.
Слање пакета може бити као емитовање:
удп_соцкет.сетсоцкопт(соцкет.СОЛ_СОЦКЕТ, соцкет.СО_БРОАДЦАСТ, 1) #пребаците утичницу у режим емитовања рз=удп_соцкет.сендто(пацкетацк, (гцонфиг["броадцаст"],68))
, и на адресу „одакле је дошао пакет“:
удп_соцкет.сетсоцкопт(соцкет.СОЛ_СОЦКЕТ,соцкет.СО_РЕУСЕАДДР,1) # пребаците сокет у режим са више слушалаца рз=удп_соцкет.сендто(пацкетацк, аддр)
, где СОЛ_СОЦКЕТ значи „ниво протокола“ за подешавање опција,
, СО_БРОАДЦАСТ опција да је пакет кациге „емитован“
Опција ,СО_РЕУСЕАДДР пребацује сокет у режим „много слушалаца“. У теорији, то је у овом случају непотребно, али на једном од ФрееБСД сервера на којем сам тестирао код није функционисао без ове опције.
Парсирање ДХЦП пакета
Овде ми се заиста допао Питхон. Испоставило се да вам омогућава да будете прилично флексибилни са бајткодом. Омогућавајући да се врло лако преведе у децималне вредности, низове и хексадецималне – тј. то је оно што нам је заправо потребно да бисмо разумели структуру пакета. Тако, на пример, можете добити опсег бајтова у ХЕКС и само бајтове: