Aprendendo Python (un pouco máis que desde cero 😉)
substitución do servidor DB2DHCP (o meu garfo), orixinal aquí, que é cada vez máis difícil de montar para o novo sistema operativo. E non me gusta que sexa un binario que non hai forma de "cambiar agora mesmo"
obter un servidor DHCP que funcione coa capacidade de seleccionar o enderezo IP do abonado mediante a combinación de mac do abonado ou cambiar mac+porto (Opción 82)
escribir outra bicicleta (Oh! esta é a miña actividade favorita)
recibindo comentarios sobre o teu club en Habrahabr (ou mellor aínda, unha invitación) 😉
Resultado: funciona 😉 Probado en FreeBSD e Ubuntu OS. Teoricamente, pódese pedir que o código funcione en calquera sistema operativo, porque Parece que non hai ligazóns específicas no código.
Coidado! Hai moito máis por vir.
Ligazón ao repositorio para afeccionados "tocar vivo".
O proceso de instalación, configuración e uso do resultado de "estudar o hardware" é moito menor, e despois un pouco de teoría sobre o protocolo DHCP. Para min. E pola historia 😉
Un pouco de teoría
Que é DHCP
Este é un protocolo de rede que permite que un dispositivo descubra o seu enderezo IP (e outros parámetros como pasarela, DNS, etc.) desde un servidor DHCP. Os paquetes intercambian mediante o protocolo UDP. O principio xeral de funcionamento do dispositivo cando se solicitan parámetros de rede é o seguinte:
O dispositivo (cliente) envía unha solicitude de difusión UDP (DHCPDISCOVER) por toda a rede coa solicitude "ben, alguén me dá un enderezo IP". Ademais, normalmente (pero non sempre) a solicitude prodúcese dende o porto 68 (fonte) e o destino é o porto 67 (destino). Algúns dispositivos tamén envían paquetes desde o porto 67. O enderezo MAC do dispositivo cliente inclúese dentro do paquete DHCPDISCOVER.
Todos os servidores DHCP situados na rede (e pode haber varios deles) forman unha oferta DHCPOFFER con axustes de rede para o dispositivo que enviou DHCPDISCOVER e tamén o emiten pola rede. A identificación de quen está destinado este paquete baséase no enderezo MAC do cliente proporcionado anteriormente na solicitude DHCPDISCOVER.
O cliente acepta paquetes con propostas de configuración de rede, selecciona o máis atractivo (os criterios poden ser diferentes, por exemplo, a hora de entrega do paquete, o número de rutas intermedias) e realiza unha "solicitude oficial" DHCPREQUEST coa configuración da rede. desde o servidor DHCP que lle gusta. Neste caso, o paquete vai a un servidor DHCP específico.
O servidor que recibiu a DHCPREQUEST envía un paquete de formato DHCPACK, no que volve a enumerar a configuración de rede destinada a este cliente
Ademais, hai paquetes DHCPINFORM que proveñen do cliente, e cuxo propósito é informar ao servidor DHCP de que o "cliente está vivo" e está a usar a configuración de rede emitida. Na implementación deste servidor, estes paquetes son ignorados.
Formato do paquete
En xeral, unha trama de paquete Ethernet ten un aspecto similar ao seguinte:
No noso caso, consideraremos só os datos directamente do contido do paquete UDP, sen cabeceiras de protocolo de capa OSI, é dicir, a estrutura DHCP:
DHCPDESCUBRIR
Así, o proceso de obtención dun enderezo IP para un dispositivo comeza co cliente DHCP que envía unha solicitude de difusión desde o porto 68 ata 255.255.255.255:67. Neste paquete, o cliente inclúe o seu enderezo MAC, así como o que quere recibir exactamente do servidor DHCP. A estrutura do paquete descríbese na seguinte táboa.
Táboa de estrutura de paquetes DHCPDISCOVER
Posición no paquete
Nome do valor
Exemplo
Introdución
Byte
Esclarecemento
1
Solicitude de arranque
1
Feitizo
1
Tipo de mensaxe. 1 - solicitude de cliente a servidor, 2 - resposta de servidor a cliente
2
Tipo de hardware
1
Feitizo
1
Tipo de enderezo de hardware, neste protocolo 1 - MAC
3
Lonxitude de enderezos de hardware
6
Feitizo
1
Lonxitude do enderezo MAC do dispositivo
4
Lúpulo
1
Feitizo
1
Número de rutas intermedias
5
ID de transacción
23:cf:de:1d
Feitizo
4
Identificador único de transacción. Xerado polo cliente ao comezo dunha operación de solicitude
7
Segundo pasou
0
Feitizo
4
Tempo en segundos desde o inicio do proceso de obtención dun enderezo
9
Bandeiras de arranque
0
Feitizo
2
Algunhas bandeiras que se poden configurar para indicar parámetros de protocolo
11
Enderezo IP do cliente
0.0.0.0
Liña
4
Enderezo IP do cliente (se o hai)
15
O enderezo IP do teu cliente
0.0.0.0
Liña
4
Enderezo IP ofrecido polo servidor (se está dispoñible)
19
O seguinte enderezo IP do servidor
0.0.0.0
Liña
4
Enderezo IP do servidor (se se coñece)
23
Enderezo IP do axente de retransmisión
172.16.114.41
Liña
4
Enderezo IP do axente de retransmisión (por exemplo, un interruptor)
27
Enderezo MAC do cliente
14:d6:4d:a7:c9:55
Feitizo
6
Enderezo MAC do remitente do paquete (cliente)
31
Recheo de enderezos de hardware do cliente
Feitizo
10
Asento reservado. Normalmente está cheo de ceros
41
Nome do servidor do servidor
Liña
64
Nome do servidor DHCP. Normalmente non se transmite
105
Nome do ficheiro de arranque
Liña
128
Nome do ficheiro no servidor utilizado polas estacións sen disco ao iniciar
235
Galletas máxicas
63: 82: 53: 63
Feitizo
4
Número "máxico", segundo o cal, incl. pode determinar que este paquete pertence ao protocolo DHCP
Opcións de DHCP. Pode ir en calquera orde
236
Número de opción
53
decembro
1
Opción 53, que especifica o tipo de paquete DHCP
Número de opción
50
decembro
1
Que enderezo IP quere recibir o cliente?
Duración da opción
4
decembro
1
Valor da opción
172.16.134.61
Liña
4
Número de opción
55
1
Parámetros de rede solicitados polo cliente. A composición pode variar
01 — Máscara de rede
03 - Pasarela
06 - DNS
oc — Nome do servidor
0f - nome de dominio da rede
1c - enderezo da solicitude de emisión (emisión)
42 - Nome do servidor TFTP
79 - Ruta estática sen clase
Duración da opción
8
1
Valor da opción
01:03:06:0c:0f:1c:42:79
8
Número de opción
82
decembro
Opción 82, que transmite o enderezo MAC do dispositivo repetidor e algúns valores adicionais.
Na maioría das veces, este é o porto do switch no que se executa o cliente DHCP final. Esta opción contén parámetros adicionais. O primeiro byte é o número da "subopción", o segundo é a súa lonxitude e despois o seu valor.
Neste caso, na opción 82, as subopcións están aniñadas:
ID do circuíto do axente = 00:04:00:01:00:04, onde os dous últimos bytes son o porto do cliente DHCP do que procedeu a solicitude
ID de axente remoto = 00:06:c8:be:19:93:11:48 - Enderezo MAC do dispositivo repetidor DHCP
Duración da opción
18
decembro
Valor da opción
01:06
00:04:00:01:00:04
02:08
00:06:c8:be:19:93:11:48
Feitizo
Fin do paquete
255
decembro
1
255 simboliza o final do paquete
OFERTA DHCP
En canto o servidor recibe o paquete DHCPDISCOVER e se ve que pode ofrecerlle ao cliente algo do solicitado, xera unha resposta para iso - DHCPDISCOVER. A resposta envíase ao porto “de onde veu”, por emisión, porque neste momento, o cliente aínda non ten un enderezo IP, polo que só pode aceptar o paquete se é enviado por emisión. O cliente recoñece que se trata dun paquete para el polo seu enderezo MAC dentro do paquete, así como polo número de transacción que xera no momento en que se crea o primeiro paquete.
Táboa de estrutura de paquetes DHCPOFFER
Posición no paquete
Nome do valor (común)
Exemplo
Introdución
Byte
Esclarecemento
1
Solicitude de arranque
1
Feitizo
1
Tipo de mensaxe. 1 - solicitude de cliente a servidor, 2 - resposta de servidor a cliente
2
Tipo de hardware
1
Feitizo
1
Tipo de enderezo de hardware, neste protocolo 1 - MAC
3
Lonxitude de enderezos de hardware
6
Feitizo
1
Lonxitude do enderezo MAC do dispositivo
4
Lúpulo
1
Feitizo
1
Número de rutas intermedias
5
ID de transacción
23:cf:de:1d
Feitizo
4
Identificador único de transacción. Xerado polo cliente ao comezo dunha operación de solicitude
7
Segundo pasou
0
Feitizo
4
Tempo en segundos desde o inicio do proceso de obtención dun enderezo
9
Bandeiras de arranque
0
Feitizo
2
Algunhas bandeiras que se poden configurar para indicar parámetros de protocolo. Neste caso, 0 significa o tipo de solicitude Unicast
11
Enderezo IP do cliente
0.0.0.0
Liña
4
Enderezo IP do cliente (se o hai)
15
O enderezo IP do teu cliente
172.16.134.61
Liña
4
Enderezo IP ofrecido polo servidor (se está dispoñible)
19
O seguinte enderezo IP do servidor
0.0.0.0
Liña
4
Enderezo IP do servidor (se se coñece)
23
Enderezo IP do axente de retransmisión
172.16.114.41
Liña
4
Enderezo IP do axente de retransmisión (por exemplo, un interruptor)
27
Enderezo MAC do cliente
14:d6:4d:a7:c9:55
Feitizo
6
Enderezo MAC do remitente do paquete (cliente)
31
Recheo de enderezos de hardware do cliente
Feitizo
10
Asento reservado. Normalmente está cheo de ceros
41
Nome do servidor do servidor
Liña
64
Nome do servidor DHCP. Normalmente non se transmite
105
Nome do ficheiro de arranque
Liña
128
Nome do ficheiro no servidor utilizado polas estacións sen disco ao iniciar
235
Galletas máxicas
63: 82: 53: 63
Feitizo
4
Número "máxico", segundo o cal, incl. pode determinar que este paquete pertence ao protocolo DHCP
Opcións de DHCP. Pode ir en calquera orde
236
Número de opción
53
decembro
1
Opción 53, que define o tipo de paquete DHCP 2 - DHCPOFFER
Duración da opción
1
decembro
1
Valor da opción
2
decembro
1
Número de opción
1
decembro
1
Opción para ofrecer ao cliente DHCP unha máscara de rede
Duración da opción
4
decembro
1
Valor da opción
255.255.224.0
Liña
4
Número de opción
3
decembro
1
Opción para ofrecer ao cliente DHCP unha pasarela predeterminada
Duración da opción
4
decembro
1
Valor da opción
172.16.12.1
Liña
4
Número de opción
6
decembro
1
Opción para ofrecer DHCP ao cliente DNS
Duración da opción
4
decembro
1
Valor da opción
8.8.8.8
Liña
4
Número de opción
51
decembro
1
A vida útil dos parámetros de rede emitidos en segundos, despois do cal o cliente DHCP debe solicitalos de novo
Duración da opción
4
decembro
1
Valor da opción
86400
decembro
4
Número de opción
82
decembro
1
Opción 82, repite o que veu en DHCPDISCOVER
Duración da opción
18
decembro
1
Valor da opción
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
decembro
18
Fin do paquete
255
decembro
1
255 simboliza o final do paquete
SOLICITUDE DHCP
Despois de que o cliente recibe DHCPOFFER, forma un paquete solicitando parámetros de rede non a todos os servidores DHCP da rede, senón só a un específico, cuxa oferta DHCPOFFER "lle gustou" máis. Os criterios de "gústame" poden ser diferentes e depender da implementación de DHCP do cliente. O destinatario da solicitude especifícase mediante o enderezo MAC do servidor DHCP. Ademais, o cliente pode enviar un paquete DHCPREQUEST sen xerar previamente DHCPDISCOVER, se o enderezo IP do servidor xa se obtivo previamente.
Táboa de estrutura de paquetes DHCPREQUEST
Posición no paquete
Nome do valor (común)
Exemplo
Introdución
Byte
Esclarecemento
1
Solicitude de arranque
1
Feitizo
1
Tipo de mensaxe. 1 - solicitude de cliente a servidor, 2 - resposta de servidor a cliente
2
Tipo de hardware
1
Feitizo
1
Tipo de enderezo de hardware, neste protocolo 1 - MAC
3
Lonxitude de enderezos de hardware
6
Feitizo
1
Lonxitude do enderezo MAC do dispositivo
4
Lúpulo
1
Feitizo
1
Número de rutas intermedias
5
ID de transacción
23:cf:de:1d
Feitizo
4
Identificador único de transacción. Xerado polo cliente ao comezo dunha operación de solicitude
7
Segundo pasou
0
Feitizo
4
Tempo en segundos desde o inicio do proceso de obtención dun enderezo
9
Bandeiras de arranque
8000
Feitizo
2
Algunhas bandeiras que se poden configurar para indicar parámetros de protocolo. Neste caso, establécese "difusión".
11
Enderezo IP do cliente
0.0.0.0
Liña
4
Enderezo IP do cliente (se o hai)
15
O enderezo IP do teu cliente
172.16.134.61
Liña
4
Enderezo IP ofrecido polo servidor (se está dispoñible)
19
O seguinte enderezo IP do servidor
0.0.0.0
Liña
4
Enderezo IP do servidor (se se coñece)
23
Enderezo IP do axente de retransmisión
172.16.114.41
Liña
4
Enderezo IP do axente de retransmisión (por exemplo, un interruptor)
27
Enderezo MAC do cliente
14:d6:4d:a7:c9:55
Feitizo
6
Enderezo MAC do remitente do paquete (cliente)
31
Recheo de enderezos de hardware do cliente
Feitizo
10
Asento reservado. Normalmente está cheo de ceros
41
Nome do servidor do servidor
Liña
64
Nome do servidor DHCP. Normalmente non se transmite
105
Nome do ficheiro de arranque
Liña
128
Nome do ficheiro no servidor utilizado polas estacións sen disco ao iniciar
235
Galletas máxicas
63: 82: 53: 63
Feitizo
4
Número "máxico", segundo o cal, incl. pode determinar que este paquete pertence ao protocolo DHCP
Opcións de DHCP. Pode ir en calquera orde
236
Número de opción
53
decembro
3
Opción 53, que define o tipo de paquete DHCP 3 - DHCPREQUEST
Duración da opción
1
decembro
1
Valor da opción
3
decembro
1
Número de opción
61
decembro
1
ID de cliente: 01 (para Ehernet) + enderezo MAC do cliente
Duración da opción
7
decembro
1
Valor da opción
01:2c:ab:25:ff:72:a6
Feitizo
7
Número de opción
60
decembro
"Identificador de clase de provedor". No meu caso, informa da versión do cliente DHCP. Quizais outros dispositivos devolvan algo diferente. Windows, por exemplo, informa MSFT 5.0
Duración da opción
11
decembro
Valor da opción
udhcp 0.9.8
Liña
Número de opción
55
1
Parámetros de rede solicitados polo cliente. A composición pode variar
01 — Máscara de rede
03 - Pasarela
06 - DNS
oc — Nome do servidor
0f - nome de dominio da rede
1c - enderezo da solicitude de emisión (emisión)
42 - Nome do servidor TFTP
79 - Ruta estática sen clase
Duración da opción
8
1
Valor da opción
01:03:06:0c:0f:1c:42:79
8
Número de opción
82
decembro
1
Opción 82, repite o que veu en DHCPDISCOVER
Duración da opción
18
decembro
1
Valor da opción
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
decembro
18
Fin do paquete
255
decembro
1
255 simboliza o final do paquete
DHCPACK
Como confirmación de que "si, é certo, este é o teu enderezo IP, e non llo darei a ninguén máis" desde o servidor DHCP, serve un paquete en formato DHCPACK do servidor ao cliente. Envíase difundido igual que outros paquetes. Aínda que, no código de abaixo para un servidor DHCP implementado en Python, por se acaso, duplico calquera solicitude de difusión enviando un paquete a unha IP de cliente específica, se xa se coñece. Ademais, ao servidor DHCP non lle importa en absoluto se o paquete DHCPACK chegou ao cliente. Se o cliente non recibe DHCPACK, despois dun tempo simplemente repite DHCPREQUEST
Táboa de estrutura de paquetes DHCPACK
Posición no paquete
Nome do valor (común)
Exemplo
Introdución
Byte
Esclarecemento
1
Solicitude de arranque
2
Feitizo
1
Tipo de mensaxe. 1 - solicitude de cliente a servidor, 2 - resposta de servidor a cliente
2
Tipo de hardware
1
Feitizo
1
Tipo de enderezo de hardware, neste protocolo 1 - MAC
3
Lonxitude de enderezos de hardware
6
Feitizo
1
Lonxitude do enderezo MAC do dispositivo
4
Lúpulo
1
Feitizo
1
Número de rutas intermedias
5
ID de transacción
23:cf:de:1d
Feitizo
4
Identificador único de transacción. Xerado polo cliente ao comezo dunha operación de solicitude
7
Segundo pasou
0
Feitizo
4
Tempo en segundos desde o inicio do proceso de obtención dun enderezo
9
Bandeiras de arranque
8000
Feitizo
2
Algunhas bandeiras que se poden configurar para indicar parámetros de protocolo. Neste caso, establécese "difusión".
11
Enderezo IP do cliente
0.0.0.0
Liña
4
Enderezo IP do cliente (se o hai)
15
O enderezo IP do teu cliente
172.16.134.61
Liña
4
Enderezo IP ofrecido polo servidor (se está dispoñible)
19
O seguinte enderezo IP do servidor
0.0.0.0
Liña
4
Enderezo IP do servidor (se se coñece)
23
Enderezo IP do axente de retransmisión
172.16.114.41
Liña
4
Enderezo IP do axente de retransmisión (por exemplo, un interruptor)
27
Enderezo MAC do cliente
14:d6:4d:a7:c9:55
Feitizo
6
Enderezo MAC do remitente do paquete (cliente)
31
Recheo de enderezos de hardware do cliente
Feitizo
10
Asento reservado. Normalmente está cheo de ceros
41
Nome do servidor do servidor
Liña
64
Nome do servidor DHCP. Normalmente non se transmite
105
Nome do ficheiro de arranque
Liña
128
Nome do ficheiro no servidor utilizado polas estacións sen disco ao iniciar
235
Galletas máxicas
63: 82: 53: 63
Feitizo
4
Número "máxico", segundo o cal, incl. pode determinar que este paquete pertence ao protocolo DHCP
Opcións de DHCP. Pode ir en calquera orde
236
Número de opción
53
decembro
3
Opción 53, que define o tipo de paquete DHCP 5 - DHCPACK
Duración da opción
1
decembro
1
Valor da opción
5
decembro
1
Número de opción
1
decembro
1
Opción para ofrecer ao cliente DHCP unha máscara de rede
Duración da opción
4
decembro
1
Valor da opción
255.255.224.0
Liña
4
Número de opción
3
decembro
1
Opción para ofrecer ao cliente DHCP unha pasarela predeterminada
Duración da opción
4
decembro
1
Valor da opción
172.16.12.1
Liña
4
Número de opción
6
decembro
1
Opción para ofrecer DHCP ao cliente DNS
Duración da opción
4
decembro
1
Valor da opción
8.8.8.8
Liña
4
Número de opción
51
decembro
1
A vida útil dos parámetros de rede emitidos en segundos, despois do cal o cliente DHCP debe solicitalos de novo
Duración da opción
4
decembro
1
Valor da opción
86400
decembro
4
Número de opción
82
decembro
1
Opción 82, repite o que veu en DHCPDISCOVER
Duración da opción
18
decembro
1
Valor da opción
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
decembro
18
Fin do paquete
255
decembro
1
255 simboliza o final do paquete
Instalación
A instalación en realidade consiste na instalación dos módulos python necesarios para o traballo. Suponse que MySQL xa está instalado e configurado.
Creamos unha base de datos MySQL, cargamos nela o volcado pydhcp.sql e configuramos o ficheiro de configuración.
Configuración
Toda a configuración do servidor está nun ficheiro xml. Ficheiro de referencia:
1.0 0.0.0.0 255.255.255.255 192.168.0.71 8600 1 255.255.255.0 192.168.0.1 localhost proba proba pydhcp opción_8.8.8.8_hex:sw_port82:1:20 opción_22_hex:sw_port82:2:16 opción_18_hex:sw_mac:82:26 40 seleccione ip, máscara, enrutador, dns dos usuarios onde upper(mac)=upper('{option_3_AgentRemoteId_hex}') e upper(port)=upper('{option_1_AgentCircuitId_port_hex}') seleccione ip, máscara, enrutador, dns dos usuarios onde upper(mac)=upper('{sw_mac}') e upper(port)=upper('{sw_port82}') seleccione ip, máscara, enrutador, dns dos usuarios onde upper(mac)=upper('{ClientMacAddress}') inserir no historial (id,dt,mac,ip,comment) valores (null,now(),'{ClientMacAddress}','{RequestedIpAddress}','DHCPACK/INFORM')
Agora con máis detalle sobre as etiquetas:
A sección dhcpserver describe a configuración básica para iniciar o servidor, a saber:
host: que enderezo IP escoita o servidor no porto 67
broadcast: cal ip é a transmisión para DHCPOFFER e DHCPACK
DHCPServer - cal é a ip do servidor DHCP
Tempo de arrendamento LeaseTime do enderezo IP emitido
ThreadLimit: cantos fíos se executan simultaneamente para procesar os paquetes UDP entrantes no porto 67. Suponse que axuda en proxectos de alta carga 😉
defaultMask,defaultRouter,defaultDNS: o que se ofrece ao subscritor por defecto se se atopa unha IP na base de datos, pero non se especifican parámetros adicionais para iso
sección mysql:
host, nome de usuario, contrasinal, nome base: todo fala por si só. Cómprese unha estrutura aproximada da base de datos GitHub
Sección de consulta: as solicitudes para recibir OFERTA/ACK descríbense aquí:
offer_count — o número de liñas con solicitudes que devolven un resultado como ip, mask, router, dns
offer_n — cadea de consulta. Se a devolución está baleira, executa a seguinte solicitude de oferta
history_sql - unha consulta que escribe, por exemplo, no "historial de autorizacións" dun subscritor
As solicitudes poden incluír calquera variable da sección de opcións ou opcións do protocolo DHCP.
Sección de opcións. Aquí é onde se fai máis interesante. Aquí podemos crear variables que podemos usar máis tarde na sección de consulta.
Por exemplo:
option_82_hex:sw_port1:20:22
, esta liña de comandos toma toda a liña que veu na solicitude DHCP para a opción 82, en formato hexadecimal, no intervalo de bytes 20 a 22 inclusive e colócaa na nova variable sw_port1 (cambiar o porto de onde veu a solicitude)
option_82_hex:sw_mac:26:40
, define a variable sw_mac, tomando o hexadecimal do intervalo 26:40
Podes ver todas as opcións posibles que se poden usar nas consultas iniciando o servidor co interruptor -d. Veremos algo así como este rexistro:
En consecuencia, podemos envolver calquera variable en {} e utilizarase na consulta SQL.
Imos rexistrar para o historial que o cliente recibiu o enderezo IP:
Iniciando o servidor
./pydhcpdb.py -d -c config.xml
— d modo de saída da consola DEBUG
- c <filename> ficheiro de configuración
Debriefing
E agora máis detalles sobre a implementación do servidor en Python. É unha dor. Python aprendeuse sobre a marcha. Moitos momentos fanse ao estilo de "Guau, dalgún xeito o fixen funcionar". Non está optimizado en absoluto, e deixouse nesta forma principalmente debido á pouca experiencia no desenvolvemento de Python. Deterereime nos aspectos máis interesantes da implementación do servidor en "código".
Analizador de ficheiros de configuración XML
Utilízase o módulo estándar de Python xml.dom. Parece sinxelo, pero durante a implementación houbo unha notable falta de documentación e exemplos claros na rede usando este módulo.
tree = minidom.parse(gconfig["config_file"]) mconfig=tree.getElementsByTagName("mysql") para elem en mconfig: gconfig["mysql_host"]=elem.getElementsByTagName("host")[0].firstChild.data gconfig["mysql_username"]=elem.getElementsByTagName("username")[0].firstChild.data gconfig["mysql_password"]=elem.getElementsByTagName("contrasinal")[0].firstChild.data gconfig["mysql_basename"] =elem.getElementsByTagName("basename")[0].firstChild.data dconfig=tree.getElementsByTagName("dhcpserver") para elem en 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_default] =elem.getElementsByTagName("defaultMask")[0].firstChild.data gconfig["dhcp_defaultRouter"]=elem.getElementsByTagName("defaultRouter")[0].firstChild.data gconfig["dhcp_defaultRouter"]=elem.getElementsByTagName("defaultRouter")[0].firstChild.data gconfig["dhcp_defaultRouter"] defaultDNS")[0].firstChild.data qconfig=tree.getElementsByTagName("consulta") para elem en qconfig: gconfig["offer_count"]=elem.getElementsByTagName("offer_count")[1].firstChild.data para num en intervalo(int(gconfig["offer_count"])): gconfig["offer_"+str(num+1)]=elem.getElementsByTagName("oferta_"+str(num+0))[0].firstChild.data gconfig ["history_sql"]=elem.getElementsByTagName("history_sql")[XNUMX].firstChild.data options=tree.getElementsByTagName("opcións") para o elemento en opcións: node=elem.getElementsByTagName("opción") para as opcións no nodo : optionsMod.append(options.firstChild.data)
Multithreading
Curiosamente, o multithreading en Python está implementado de forma moi clara e sinxela.
def PacketWork(data,addr): ... # implementación de analizar o paquete entrante e responder a el ... mentres que True: data, addr = udp_socket.recvfrom(1024) # esperando polo paquete UDP thread = threading.Thread( target=PacketWork , args=(data,addr,)).start() # como veu - iniciamos a función PacketWork previamente definida en segundo plano con parámetros mentres enhebramos.active_count() >gconfig["dhcp_ThreadLimit"]: time. sleep(1) # se o número Xa hai máis fíos en execución que na configuración, agardamos ata que haxa menos
Recibir/enviar paquete DHCP
Para interceptar os paquetes UDP que chegan a través da tarxeta de rede, cómpre "elevar" o socket:
AF_INET - significa que o formato de enderezo será IP: porto. Tamén pode haber AF_UNIX, onde o enderezo vén dado polo nome do ficheiro.
SOCK_DGRAM - significa que non aceptamos un "paquete en bruto", senón un que xa pasou polo firewall e cun paquete parcialmente recortado. Eses. recibimos só un paquete UDP sen o compoñente "físico" do envoltorio de paquetes UDP. Se usas a marca SOCK_RAW, tamén terás que analizar este "envoltorio".
O envío dun paquete pode ser como unha emisión:
udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #cambiar o socket ao modo broadcast rz=udp_socket.sendto(packetack, (gconfig["broadcast"],68))
, e ao enderezo "de onde veu o paquete":
udp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # cambia o socket ao modo multi-ouvir rz=udp_socket.sendto(packetack, addr)
, onde SOL_SOCKET significa o "nivel de protocolo" para configurar as opcións,
, opción SO_BROADCAST que o paquete do casco está "difundido"
A opción ,SO_REUSEADDR cambia o socket ao modo "moitos oíntes". En teoría, neste caso é innecesario, pero nun dos servidores FreeBSD nos que probei, o código non funcionaba sen esta opción.
Analizando un paquete DHCP
Aquí é onde me gustou moito Python. Resulta que fóra da caixa permíteche ser bastante flexible co bytecode. Permitindo que se traduza moi facilmente en valores decimais, cadeas e hexadecimales, é dicir. isto é o que realmente necesitamos para comprender a estrutura do paquete. Así, por exemplo, pode obter un intervalo de bytes en HEX e só bytes: