El lenguaje de desarrollo debe ser lenguaje C sobre sistema
operativo Linux y debe funcionar en los ordenadores de los
laboratorios docentes de Ingeniería Telemática, donde se realizará
la corrección presencial (existen tres máquinas disponibles para
conexión en forma remota (ssh):
monitor01.lab.it.uc3m.es, monitor02.lab.it.uc3m.es y
monitor03.lab.it.uc3m.es).
Es obligatorio utilizar el parámetro -Wall de gcc en todas las compilaciones. Las prácticas deben compilar sin ningún warning ó error.
Las prácticas no deben tener fugas de memoria (se utilizará valgrind para comprobarlo).
Las instrucciones de entrega se publicarán durante el curso, básicamente deberán incluir la entrega del código fuente (sólo ficheros .c y .h),
un fichero Makefile que lo compile y un fichero README con detalles como el nombre, email y número de grupo. No se corregirán prácticas que no cumplan con lo anterior, es decir, no se corregirán prácticas que contengan fugas de memoria, warnings ó errores durante la compilación.
Para poder realizar la práctica en los laboratorios se ha montado el entorno de pruebas DHCPlab, cuyas instrucciones de uso se pueden descargar desde aquí.
En la práctica se va a implementar una versión simplificada de la RFC. Las
simplicaciones están indicadas más abajo. La RFC completa está accesible
desde el siguiente enlace: RFC 2131.
El estándar RFC 2131 define tanto el funcionamiento del cliente como del servidor para la obtención
de parámetros de arranque y autoconfiguración. Sin embargo, para la realización
de la práctica sólo se exige implementar el cliente.
Debido a que es necesario ser root para la implementación de la práctica, se va a suministrar
un entorno de pruebas con todo el software ya instalado, incluído un servidor DHCP básico.
- Funcionamiento básico::
A continuación se explica el funcionamiento básico del protocolo DHCP, junto con algún ejemplo. No es objetivo de este
enunciado el explicar el protocolo en profundidad: debe ser el alumno, a través de la lectura de la RFC
quien complete los detalles necesarios para la correcta implementación de la práctica.
El protocolo DHCP maneja distintos tipos de paquetes de los cuales es obligatorio implementar/reconocer estos seis:
DHCPDISCOVER, DHCPOFFER, DHCPREQUEST, DHCPACK, DHCPNACK y DHCPRELEASE.
DHCP funciona sobre UDP exclusivamente, y es uno de los pocos protocolos que usa puertos específicos
tanto para servidor (puerto 67) como para cliente (puerto 68).
DHCP permite obtener diversos parámetros, como dirección IP, máscara de subred, fichero de arrranque, DNS, servidor de impresión, etc...
Como ejemplo, para obtener una dirección IP, un cliente debe intercambiar los siguientes mensajes con el servidor (véase figura):
- DHCPDISCOVER, enviado por el cliente. Se trata de un mensaje UDP multicast que es recibido por los servidores DHCP.
- DHCPOFFER, enviado por el/los servidores, donde ofertan varias direcciones IP, sobre las que el cliente debe escoger.
- DHCPREQUEST, enviado por el cliente, que es un mensaje UDP (puede ser unicast ó multicast) para solicitar una dirección específica.
- DHCPACK, enviado por el servidor, confirmando esa IP.
Existen otros mensajes como DHCPNACK y DHCPRELEASE, no mostrados en la figura anterior, que son también obligatorios implementar/reconocer.
La implementación obligatoria es por tanto, la de un cliente DHCP, el cual debe implementarse
con las siguientes consideraciones:
- Ejecutable y parámetros: el ejecutable debe llamarse
dhcpcl y debe soportar los siguientes parámetros de entrada:
dhcpcl interface [-t timeout] [-h hostname] [-a IP address] [-l leasetime] [-d]
- -t timeout: especifica (en segundos) durante cuánto tiempo el cliente
intentará conseguir una IP. Si no se especifica, el valor por defecto es de 64 segundos.
- -h hostname: indica la cadena a usar en el campo de opciones host_name del datagrama DHCP.
- -a IP address: indica la última dirección IP conocida, para
ser enviada en el DHCPDISCOVER
- -l leasetime: especifica (en segundos y en decimal) el valor del temporizador de arriendo (leasetime) sugerido al servidor.
Nótese que el servidor puede sobreescribir este valor. Si no se especifica, el valor por defecto es infinito.
- -d: modo de depuración. Los desarrolladores deben
utilizar este modo para aislar a los usuarios de los mensajes de
salida de depuración que hayan implementado.
Ejemplos y formatos de entrada/salida:
- Obtención de IP. El programa dhcpcl debe activar el interfaz primero:
; ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.255.255.0
UP LOOPBACK RUNNING MTU:1500 Metric:1
RX packets:306 errors:0 dropped:0 overruns:0 frame:0
TX packets:306 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:29504 (28.8 Kb) TX bytes:29504 (28.8 Kb)
; dhcpcl eth1 -t 15 -h zorak -a 192.168.100.25
#[2008-10-11 15:30:34+02:00] (0x12345678) pid = 13086.
#[2008-10-11 15:30:39+02:00] (0x12345678) DHCPDISCOVER sent.
#[2008-10-11 15:30:40+02:00] (0x12345678) DHCPOFFER received from 192.168.100.0 (offered 192.168.100.20).
#[2008-10-11 15:30:40+02:00] (0x12345678) DHCPREQUEST sent to 192.168.100.0.
#[2008-10-11 15:30:41+02:00] (0x12345678) DHCPACK received: 192.168.100.20 with leasing 86400 seconds.
#[2008-10-11 15:30:41+02:00] IP 192.168.100.20; leasetime 86400; subnet mask 255.255.255.0; router: 192.168.10.2; server hostname: zorak; primary DNS: 192.168.10.2; secondary DNS: 192.168.10.10
#[2008-10-11 15:32:01+02:00] SIGINT received.
; ifconfig
eth1 Link encap:Ethernet HWaddr FE:FD:00:00:01:01
inet addr:192.168.100.20 Bcast:192.168.100.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes: 0 (0 kb) TX bytes: 0 (0 Kb)
Interrupt:28
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.255.255.0
UP LOOPBACK RUNNING MTU:1500 Metric:1
RX packets:5124 errors:0 dropped:0 overruns:0 frame:0
TX packets:5124 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:129504 (128.8 Kb) TX bytes:129504 (128.8 Kb)
Obtención de IP. En este caso, debe dar error por la salida de error estándar, porque el interfaz ya está activado:
; ifconfig
eth1 Link encap:Ethernet HWaddr FE:FD:00:00:01:01
inet addr:192.168.100.20 Bcast:192.168.100.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:247 errors:1 dropped:0 overruns:0 frame:0
TX packets:446 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes: 176179 (167.98 kb) TX bytes:287587 (273.79 kb)
Interrupt:28
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.255.255.0
UP LOOPBACK RUNNING MTU:1500 Metric:1
RX packets:5124 errors:0 dropped:0 overruns:0 frame:0
TX packets:5124 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:129504 (128.8 Kb) TX bytes:129504 (128.8 Kb)
; dhcpcl eth1 -t 15 -h zorak -a 192.168.100.25
Error: eth1 is already enabled
; ifconfig
eth1 Link encap:Ethernet HWaddr FE:FD:00:00:01:01
inet addr:192.168.100.20 Bcast:192.168.100.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes: 0 (0 kb) TX bytes: 0 (0 Kb)
Interrupt:28
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.255.255.0
UP LOOPBACK RUNNING MTU:1500 Metric:1
RX packets:5124 errors:0 dropped:0 overruns:0 frame:0
TX packets:5124 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:129504 (128.8 Kb) TX bytes:129504 (128.8 Kb)
Cancelación de IP. Partiendo del interfaz desactivado, debe activarse como en el ejemplo de arriba. Posteriormente, el programa debe desactivar el interfaz:
; ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.255.255.0
UP LOOPBACK RUNNING MTU:1500 Metric:1
RX packets:306 errors:0 dropped:0 overruns:0 frame:0
TX packets:306 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:29504 (28.8 Kb) TX bytes:29504 (28.8 Kb)
; dhcpcl eth1 -t 15 -h zorak -a 192.168.100.25
#[2008-10-11 15:30:34+02:00] (0x12345678) pid = 13086.
#[2008-10-11 15:30:39+02:00] (0x12345678) DHCPDISCOVER sent.
#[2008-10-11 15:30:40+02:00] (0x12345678) DHCPOFFER received from 192.168.100.0 (offered 192.168.100.20).
#[2008-10-11 15:30:40+02:00] (0x12345678) DHCPREQUEST sent to 192.168.100.0.
#[2008-10-11 15:30:41+02:00] (0x12345678) DHCPACK received: 192.168.100.20 with leasing 86400 seconds.
#[2008-10-11 15:30:41+02:00] IP 192.168.100.20; leasetime 86400; subnet mask 255.255.255.0; router: 192.168.10.2; server hostname: zorak; primary DNS: 192.168.10.2; secondary DNS: 192.168.10.10
; ifconfig eth1
eth1 Link encap:Ethernet HWaddr FE:FD:00:00:01:01
inet addr:192.168.100.20 Bcast:192.168.100.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:247 errors:1 dropped:0 overruns:0 frame:0
TX packets:446 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes: 176179 (167.98 kb) TX bytes:287587 (273.79 kb)
Interrupt:28
; kill -SIGUSR2 13086
#[2008-10-11 15:32:01+02:00] SIGUSR2 received.
#[2008-10-11 15:30:41+02:00] (0x12345678) DHCPRELEASE sent 192.168.100.20 released.
; ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.255.255.0
UP LOOPBACK RUNNING MTU:1500 Metric:1
RX packets:306 errors:0 dropped:0 overruns:0 frame:0
TX packets:306 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:29504 (28.8 Kb) TX bytes:29504 (28.8 Kb)
Cancelación de IP. En este caso, debe dar error por la salida de error estándar, ya que interfaz desactivado (se deshabilita manualmente con #ifconfig eth1 down:
; ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.255.255.0
UP LOOPBACK RUNNING MTU:1500 Metric:1
RX packets:306 errors:0 dropped:0 overruns:0 frame:0
TX packets:306 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:29504 (28.8 Kb) TX bytes:29504 (28.8 Kb)
; dhcpcl eth1 -t 15 -h zorak -a 192.168.100.25
#[2008-10-11 15:30:34+02:00] (0x12345678) pid = 13086.
#[2008-10-11 15:30:39+02:00] (0x12345678) DHCPDISCOVER sent.
#[2008-10-11 15:30:40+02:00] (0x12345678) DHCPOFFER received from 192.168.100.0 (offered 192.168.100.20).
#[2008-10-11 15:30:40+02:00] (0x12345678) DHCPREQUEST sent to 192.168.100.0.
#[2008-10-11 15:30:41+02:00] (0x12345678) DHCPACK received: 192.168.100.20 with leasing 86400 seconds.
#[2008-10-11 15:30:41+02:00] IP 192.168.100.20; leasetime 86400; subnet mask 255.255.255.0; router: 192.168.10.2; server hostname: zorak; primary DNS: 192.168.10.2; secondary DNS: 192.168.10.10
; ifconfig eth1
eth1 Link encap:Ethernet HWaddr FE:FD:00:00:01:01
inet addr:192.168.100.20 Bcast:192.168.100.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:247 errors:1 dropped:0 overruns:0 frame:0
TX packets:446 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes: 176179 (167.98 kb) TX bytes:287587 (273.79 kb)
Interrupt:28
; ifconfig eth1 down
; ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.255.255.0
UP LOOPBACK RUNNING MTU:1500 Metric:1
RX packets:306 errors:0 dropped:0 overruns:0 frame:0
TX packets:306 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:29504 (28.8 Kb) TX bytes:29504 (28.8 Kb)
; kill -SIGUSR2 13086
#[2008-10-11 15:32:01+02:00] SIGUSR2 received.
Error: eth1 is already disabled.
Notas:
Todos los mensajes deben mostrarse por la salida estándar, excepto los mensajes de error, que deben mostrarse por la salida de error estándar.
La ejecución de ifconfig es indicativa. No es necesario desarrollar este comando.
Una vez recibidos los parámetros del servidor, el cliente sólo tendrá que configurar la dirección IP, la máscara de subred y el gateway (router). El resto de datos que puede mandarnos el servidor DHCP pueden ser ignorados por el cliente.
Trazas: es obligatorio que el programa muestre trazas que
puedan permitir el seguimiento de la ejecución. Estas trazas se deben
mostrar por la salida estándar. El estado de salida de dhcpcl
debe ser 0 si se han obtenido los parámetros del servidor correctamente,
1 si no se ha obtenido respuesta del servidor y -1 si se produce un error. Estas trazas
corresponden a los mensajes DHCP (DISCOVER, OFFER, REQUEST, ACK, NACK, RELEASE) y deben ser las siguientes:
#[timestamp] PID = pid.
#[timestamp] (xid) DHCPDISCOVER sent.
#[timestamp] (xid) DHCPOFFER received from ip_s (offered ip_c).
#[timestamp] (xid) DHCPREQUEST sent to ip_s.
#[timestamp] (xid) DHCPACK received: ip_c with leasing l seconds.
#[timestamp] (xid) DHCPNACK received.
#[timestamp] (xid) DHCPRELEASE sent ip_c released.
#[timestamp] IP ip_c; leasetime l; subnet mask subnet_mask; router: router; server hostname: server_hostname; primary DNS: primary_DNS; secondary DNS: secondary_DNS
#[timestamp] SIGINT received.
#[timestamp] SIGUSR2 received.
Siendo:
- timestamp: el tiempo del sistema, siguiendo el formato
establecido en la RFC 3339:
; date --rfc-3339=seconds
2008-10-16 10:08:02+01:00
xid: campo transactionID del datagrama DHCP.
ip_s: dirección IP del servidor DHCP.
ip_c: dirección IP arrendada por el servidor.
l: temporizador de arriendo (leasetime) anunciado por el servidor.
El resto de parámetros son autoexplicativos.
Simplificaciones a la RFC:
- No es necesaria la implementación de los mensajes DHCPINFORM ni DHCPDECLINE.
- No es necesaria ninguna implementación relativa a multi-homed hosts.
- No es necesaria la implementación de los estados REBINDING y RENEWING, ni
tampoco el uso de los temporizadores T1, T2 (véase Figura 5 de la RFC). Según la RFC, una vez que el cliente esté en estado BOUND,
existen tres temporizadores (T1 < T2 < leasetime) que se activan y que producen la transición hacia otros estados y el envío de diversos mensajes.
- Si expira T1, el cliente entra en estado RENEWING y envía un DHCPREQUEST unicast pidiendo que se le extienda el tiempo de arriendo.
- Si expira T2 sin recibir DHCPACK, el cliente entra en estado REBINDING y envía un DHCPREQUEST broadcast.
En esta práctica, desde el estado BOUND se saldrá del programa una vez expirado el tiempo leasetime (a no ser que se envíe un DHCPRELEASE con SIGUSR2).
- No es necesario que el cliente compruebe la IP recibida mediante ARP.
- El único nivel de enlace obligatorio que debe soportarse es Ethernet.
- Si el cliente recibe múltiples respuestas de varios servidores, el cliente debe elegir una de ellas. Se deja a libre elección el procedimiento para elegirla.
- Todo lo que aparezca reflejado en la RFC como MAY ó SHOULD es opcional. Todo lo que aparezca como MUST es obligatorio de implementar.
Consideraciones sobre temporizadores y timeouts: se
utilizarán siempre los valores RECOMMENDED de la RFC.
Consideraciones sobre sockets: es obligatorio usar sockets UDP siempre que se pueda (pej: DHCPRELEASE, DHCPDECLINE). Cuando no sea posible (DHCPDISCOVER, DHCPREQUEST) se usarán raw sockets.
Es decir, la implementación del cliente deberá llevar obligatoriamente una mezcla de los dos tipos de sockets.
Se ha creado una página de manual para la implementanción propuesta en
esta práctica de dhcp, que resume la información de formatos de entrada y
salida y trazas. También se puede descargar en formato HTML.