подмяна на сървъра DB2DHCP (моята вилица), оригинал тук, който става все по-труден за сглобяване за новата ОС. И не ми харесва, че това е двоичен файл, който няма начин да „промените точно сега“
получаване на работещ DHCP сървър с възможност за избор на IP адреса на абоната, използвайки mac на абоната или комбинация от превключвател mac+port (Опция 82)
писане на друг велосипед (О! това е любимото ми занимание)
получаване на коментари за вашите умения с клуб в Habrahabr (или още по-добре, покана) 😉
Резултат: работи 😉 Тествано на FreeBSD и Ubuntu OS. Теоретично кодът може да бъде помолен да работи под всяка операционна система, защото Изглежда, че няма конкретни обвързвания в кода.
Внимателно! Предстои още много.
Връзка към хранилище за аматьори "докосване жив".
Процесът на инсталиране, конфигуриране и използване на резултата от „изучаване на хардуера“ е много по-нисък, а след това малко теория за DHCP протокола. За мен. И за историята 😉
Малко теория
Какво е DHCP
Това е мрежов протокол, който позволява на устройството да открие своя IP адрес (и други параметри като шлюз, DNS и т.н.) от DHCP сървър. Пакетите се обменят с помощта на UDP протокол. Общият принцип на работа на устройството при заявка на мрежови параметри е следният:
Устройството (клиентът) изпраща UDP заявка за излъчване (DHCPDISCOVER) в цялата мрежа с искането „добре, някой да ми даде IP адрес“. Освен това обикновено (но не винаги) заявката идва от порт 68 (източник), а дестинацията е порт 67 (дестинация). Някои устройства също изпращат пакети от порт 67. MAC адресът на клиентското устройство е включен в пакета DHCPDISCOVER.
Всички DHCP сървъри, разположени в мрежата (и може да има няколко от тях), формират оферта DHCPOFFER с мрежови настройки за устройството, изпратило DHCPDISCOVER, и също така го излъчват по мрежата. Идентифицирането на това за кого е предназначен този пакет се основава на MAC адреса на клиента, предоставен по-рано в заявката DHCPDISCOVER.
Клиентът приема пакети с предложения за мрежови настройки, избира най-атрактивния (критериите могат да бъдат различни, например времето за доставка на пакета, броят на междинните маршрути) и прави „официална заявка“ DHCPREQUEST с мрежовите настройки от DHCP сървъра, който харесва. В този случай пакетът отива към определен DHCP сървър.
Сървърът, получил DHCPREQUEST, изпраща пакет във формат DHCPACK, в който отново изброява мрежовите настройки, предназначени за този клиент
Освен това има DHCPINFORM пакети, които идват от клиента и чиято цел е да информират DHCP сървъра, че „клиентът е жив“ и използва издадените мрежови настройки. При изпълнението на този сървър тези пакети се игнорират.
Формат на опаковката
Като цяло рамката на Ethernet пакет изглежда по следния начин:
В нашия случай ще разгледаме само данните директно от съдържанието на UDP пакета, без заглавките на протокола на слоя OSI, а именно DHCP структурата:
DHCPDICOVER
И така, процесът на получаване на 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
Хмел
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 пакет
Номер на опцията
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 символизира края на пакета
DHCP ОФЕРТА
Веднага след като сървърът получи DHCPDISCOVER пакета и ако види, че може да предложи на клиента нещо от заявеното, той генерира отговор за него - DHCPDISCOVER. Отговорът се изпраща до порта „откъдето е дошъл“, чрез излъчване, защото в този момент клиентът все още няма IP адрес, следователно може да приеме пакета само ако е изпратен чрез излъчване. Клиентът разпознава, че това е пакет за него по своя MAC адрес в пакета, както и по номера на транзакцията, който генерира при създаването на първия пакет.
DHCPOFFER Структурна таблица на пакети
Позиция в опаковката
Име на стойността (често срещано)
Пример
идея
байт
Изясняване
1
Заявка за зареждане
1
магия
1
Тип съобщение. 1 - заявка от клиент към сървър, 2 - отговор от сървър към клиент
2
Тип хардуер
1
магия
1
Тип хардуерен адрес, в този протокол 1 - MAC
3
Дължина на хардуерните адреси
6
магия
1
Дължина на MAC адреса на устройството
4
Хмел
1
магия
1
Брой междинни маршрути
5
Идентификационен номер на транзакцията
23:cf:de:1d
магия
4
Уникален идентификатор на транзакция. Генерира се от клиента в началото на операция по заявка
7
Изтекла втора
0
магия
4
Време в секунди от началото на процеса на получаване на адрес
9
Флагове за зареждане
0
магия
2
Определени флагове, които могат да бъдат зададени за указване на параметри на протокола. В този случай 0 означава типа Unicast заявка
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:4г:ек
Декември
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
Хмел
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
ID на клиента: 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:4г:ек
Декември
18
Край на опаковката
255
Декември
1
255 символизира края на пакета
DHCPACK
Като потвърждение, че „да, точно така, това е вашият 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
Хмел
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:4г:ек
Декември
18
Край на опаковката
255
Декември
1
255 символизира края на пакета
Инсталация
Инсталацията всъщност се състои в инсталиране на необходимите за работа Python модули. Предполага се, че 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, в шестнадесетичен формат, в диапазона от 20 до 22 байта включително, и го поставя в новата променлива sw_port1 (порт за превключване, откъдето е дошла заявката)
option_82_hex:sw_mac:26:40
, дефинирайте променливата sw_mac, като вземете шестнадесетичния код от диапазона 26:40
Можете да видите всички възможни опции, които могат да се използват в заявки, като стартирате сървъра с ключа -d. Ще видим нещо като този дневник:
Съответно можем да обвием всяка променлива в {} и тя ще бъде използвана в SQL заявката.
Нека запишем за историята, че клиентът е получил IP адреса:
Старт на сървъра
./pydhcpdb.py -d -c config.xml
— d конзолен изходен режим DEBUG
- c <име на файл> конфигурационен файл
инструктиране на отговорно лице
А сега повече подробности за внедряването на сървъра в Python. Това е болка. Python беше научен в движение. Много моменти са направени в стил „уау, някак си успях“. Изобщо не е оптимизиран и е оставен в тази форма главно поради малък опит в разработката на Python. Ще се спра на най-интересните аспекти на внедряването на сървъра в „код“.
Анализатор на XML конфигурационен файл
Използва се стандартният Python модул xml.dom. Изглежда просто, но по време на изпълнението имаше забележима липса на ясна документация и примери в мрежата, използваща този модул.
дърво = minidom.parse(gconfig["config_file"]) mconfig=tree.getElementsByTagName("mysql") за елемент в 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") за елемент в 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") за elem в 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("опция") за опции в възел : optionsMod.append(options.firstChild.data)
Многопоточност
Колкото и да е странно, многопоточността в Python е реализирана много ясно и просто.
def PacketWork(data,addr): ... # реализация на анализиране на входящия пакет и отговор на него ... while True: data, addr = udp_socket.recvfrom(1024) # изчакване на UDP пакет thread = threading.Thread( target=PacketWork , args=(data,addr,)).start() # както дойде - стартираме предварително дефинираната PacketWork функция във фонов режим с параметри, докато threading.active_count() >gconfig["dhcp_ThreadLimit"]: време. sleep(1) # ако числото Вече работят повече нишки, отколкото в настройките, изчакваме, докато останат по-малко от тях
Получаване/изпращане на DHCP пакет
За да прихванете UDP пакети, идващи през мрежовата карта, трябва да „повдигнете“ сокета:
AF_INET - означава, че форматът на адреса ще бъде IP: порт. Може да има и AF_UNIX - където адресът е даден от името на файла.
SOCK_DGRAM - означава, че не приемаме „суров пакет“, а такъв, който вече е преминал през защитната стена и с частично изрязан пакет. Тези. получаваме само UDP пакет без „физическия“ компонент на обвивката на UDP пакета. Ако използвате флага SOCK_RAW, тогава ще трябва също да анализирате тази „обвивка“.
Изпращането на пакет може да бъде като излъчване:
udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #превключване на сокета към режим на изпращане на излъчване 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 и само байтове: