mirror of
https://github.com/eblot/pybootd.git
synced 2024-09-11 22:17:44 +03:00
Update doc, and use d
suffix for local daemons/servers
This commit is contained in:
parent
6d8a7111cb
commit
3a2148537a
79
README.rst
79
README.rst
@ -21,17 +21,15 @@ Requirements
|
|||||||
Python
|
Python
|
||||||
------
|
------
|
||||||
|
|
||||||
- Python_ 2.7 or above is required. Python_ 3.x is not yet supported.
|
- Python_ 3.5+ or above is required. Python_ 2.x is not longer supported.
|
||||||
- Six_ compatibility module
|
|
||||||
- Netifaces_ Python module is required on OS X; on Linux only, iproute2_ can be
|
- Netifaces_ Python module is required on OS X; on Linux only, iproute2_ can be
|
||||||
used as an alternative
|
used as an alternative
|
||||||
- Optional: python-pkg-resources_ Python module
|
- Optional: python_pkg_resources_ Python module
|
||||||
|
|
||||||
.. _Python: http://python.org/
|
.. _Python: http://python.org/
|
||||||
.. _Netifaces: http://alastairs-place.net/netifaces/
|
.. _Netifaces: http://alastairs-place.net/netifaces/
|
||||||
.. _iproute2: http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2
|
.. _iproute2: http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2
|
||||||
.. _python-pkg-resources: http://pythonhosted.org/distribute/pkg_resources.html
|
.. _python_pkg_resources: http://pythonhosted.org/distribute/pkg_resources.html
|
||||||
.. _Six: http://pythonhosted.org/six
|
|
||||||
|
|
||||||
Permissions
|
Permissions
|
||||||
-----------
|
-----------
|
||||||
@ -81,7 +79,7 @@ Common errors
|
|||||||
``pybootd.pxed.BootpError: Unable to detect network configuration``
|
``pybootd.pxed.BootpError: Unable to detect network configuration``
|
||||||
This error is often triggered when the ``pool_start`` address is not
|
This error is often triggered when the ``pool_start`` address is not
|
||||||
part of a valid network. Double check the network configuration and
|
part of a valid network. Double check the network configuration and
|
||||||
fix up the ``[bootp]`` section so that it matches the actual
|
fix up the ``[bootpd]`` section so that it matches the actual
|
||||||
network. If you don't want to allocate addresses dynamically from
|
network. If you don't want to allocate addresses dynamically from
|
||||||
the pool (with ``pool_count = 0``), you still need to specify
|
the pool (with ``pool_count = 0``), you still need to specify
|
||||||
``pool_start`` to some address in the local network you want to
|
``pool_start`` to some address in the local network you want to
|
||||||
@ -95,8 +93,8 @@ Common errors
|
|||||||
Configuration
|
Configuration
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
``pybootd`` has a few option switches. The server offers two services: bootp
|
``pybootd`` has a few option switches. The server offers two services: *bootpd*
|
||||||
(which supports Dhcp and PXE extensions) and tftp. It is possible to disable
|
(which supports DHCP and PXE extensions) and *tftpd*. It is possible to disable
|
||||||
either services.
|
either services.
|
||||||
|
|
||||||
Usage: pybootd.py [options]
|
Usage: pybootd.py [options]
|
||||||
@ -145,8 +143,8 @@ client requests at least an IP address twice:
|
|||||||
``file``
|
``file``
|
||||||
The path to the output log file, if ``type`` is set to ``file``.
|
The path to the output log file, if ``type`` is set to ``file``.
|
||||||
|
|
||||||
``[bootp]`` section
|
``[bootpd]`` section
|
||||||
...................
|
....................
|
||||||
|
|
||||||
``access``
|
``access``
|
||||||
Type of access control list. If this option is not defined, all BOOTP
|
Type of access control list. If this option is not defined, all BOOTP
|
||||||
@ -228,36 +226,40 @@ client requests at least an IP address twice:
|
|||||||
``servername``
|
``servername``
|
||||||
Name of the BOOTP server.
|
Name of the BOOTP server.
|
||||||
|
|
||||||
|
|
||||||
``[mac]`` section
|
``[mac]`` section
|
||||||
.................
|
.................
|
||||||
|
|
||||||
The ``[mac]`` section contains one entry for each MAC address to allow or
|
The ``[mac]`` section contains one entry for each MAC address to allow or
|
||||||
block. The value for each entry is a boolean, *i.e.*::
|
block. The value for each entry is a boolean, *i.e.*::
|
||||||
|
|
||||||
AA-BB-CC-DD-EE-FF = enable
|
``AA-BB-CC-DD-EE-FF = enable``
|
||||||
|
|
||||||
|
Note that due to a limitation of the configuration parser, ':' byte separator
|
||||||
|
in MAC addresses is not allowed, please use '-' separator.
|
||||||
|
|
||||||
Note that due to a limitation of the configuration parser, ':' byte separator
|
|
||||||
in MAC addresses is not allowed, please use '-' separator.
|
|
||||||
|
|
||||||
``[static_dhcp]`` section
|
``[static_dhcp]`` section
|
||||||
.........................
|
.........................
|
||||||
|
|
||||||
The ``[static_dhcp]`` section contains one entry for each MAC
|
The ``[static_dhcp]`` section contains one entry for each MAC
|
||||||
address to associate with a specific IP address. The IP address can be
|
address to associate with a specific IP address. The IP address can be
|
||||||
any IPv4 address in dotted notation, *i.e.*:
|
any IPv4 address in dotted notation, *i.e.*:
|
||||||
|
|
||||||
AA-BB-CC-DD-EE-FF = 192.168.1.2
|
``AA-BB-CC-DD-EE-FF = 192.168.1.2``
|
||||||
|
|
||||||
|
The MAC addresses specified here will automatically be allowed,
|
||||||
|
unless ``[mac]`` section specifies otherwise.
|
||||||
|
|
||||||
The MAC addresses specified here will automatically be allowed,
|
|
||||||
unless ``[mac]`` section specifies otherwise.
|
|
||||||
|
|
||||||
``[uuid]`` section
|
``[uuid]`` section
|
||||||
..................
|
..................
|
||||||
|
|
||||||
The ``[uuid]`` section contains one entry for each UUID to allow or block.
|
The ``[uuid]`` section contains one entry for each UUID to allow or block.
|
||||||
The value for each entry is a boolean, *i.e.*::
|
The value for each entry is a boolean, *i.e.*::
|
||||||
|
|
||||||
|
``xxxxxxxx-aaaa-bbbb-cccc-yyyyyyyyyyyy = enable``
|
||||||
|
|
||||||
xxxxxxxx-aaaa-bbbb-cccc-yyyyyyyyyyyy = enable
|
|
||||||
|
|
||||||
``[http]`` section
|
``[http]`` section
|
||||||
..................
|
..................
|
||||||
@ -281,8 +283,9 @@ The ``pxe``/``dhcp`` option pair enables the remote HTTP server to identify
|
|||||||
the boot phase: either a BIOS initialization or an OS boot sequence. When such
|
the boot phase: either a BIOS initialization or an OS boot sequence. When such
|
||||||
differentiation is useless, both options may refer to the same path.
|
differentiation is useless, both options may refer to the same path.
|
||||||
|
|
||||||
``[tftp]`` section
|
|
||||||
..................
|
``[tftpd]`` section
|
||||||
|
...................
|
||||||
|
|
||||||
``address``
|
``address``
|
||||||
Address to listen to incoming TFTP requests. When the BOOTP daemon is
|
Address to listen to incoming TFTP requests. When the BOOTP daemon is
|
||||||
@ -310,11 +313,12 @@ differentiation is useless, both options may refer to the same path.
|
|||||||
- an absolute path, when the ``root`` option starts with ``/``,
|
- an absolute path, when the ``root`` option starts with ``/``,
|
||||||
- a URL prefix, to access remote files.
|
- a URL prefix, to access remote files.
|
||||||
|
|
||||||
|
|
||||||
``[filters]`` section
|
``[filters]`` section
|
||||||
.....................
|
.....................
|
||||||
|
|
||||||
The ``filters`` section allows on-the-fly pathnames transformation. When a TFTP
|
The ``filters`` section allows on-the-fly pathnames transformation. When a TFTP
|
||||||
client requests some specific filenames, the *tftp* server can translate them
|
client requests some specific filenames, the *tftpd* server can translate them
|
||||||
to other ones.
|
to other ones.
|
||||||
|
|
||||||
This option is useful to serve the very same configuration file (''e.g.''
|
This option is useful to serve the very same configuration file (''e.g.''
|
||||||
@ -332,8 +336,8 @@ braces, such as ``{varname}``.
|
|||||||
For now, the only supported variable is ``filename``, which is replaced with
|
For now, the only supported variable is ``filename``, which is replaced with
|
||||||
the actual requested filename.
|
the actual requested filename.
|
||||||
|
|
||||||
The *value* part can also contain a special marker, that tells the *tftp*
|
The *value* part can also contain a special marker, that tells the *tftpd*
|
||||||
daemon to read the replacement pattern from a file. This special marker should
|
server to read the replacement pattern from a file. This special marker should
|
||||||
be written with enclosing brackets, such as ``[file]``.
|
be written with enclosing brackets, such as ``[file]``.
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
@ -343,7 +347,7 @@ The following filter::
|
|||||||
|
|
||||||
pxelinux.cfg/* = pybootd/etc/pxe.cfg
|
pxelinux.cfg/* = pybootd/etc/pxe.cfg
|
||||||
|
|
||||||
tells the *tftp* server that all client requests matching the
|
tells the *tftpd* server that all client requests matching the
|
||||||
``pxelinux.cfg/*`` pattern should be served the ``pybootd/etc/pxe.cfg`` file
|
``pxelinux.cfg/*`` pattern should be served the ``pybootd/etc/pxe.cfg`` file
|
||||||
instead. This prevents the client to perform the usual time-costing fallback
|
instead. This prevents the client to perform the usual time-costing fallback
|
||||||
requests using UUID, MAC, and suffix addresses before eventually falling
|
requests using UUID, MAC, and suffix addresses before eventually falling
|
||||||
@ -353,7 +357,7 @@ The following filter::
|
|||||||
|
|
||||||
startup = [dir/{filename}.cfg]
|
startup = [dir/{filename}.cfg]
|
||||||
|
|
||||||
tells the *tftp* server that when the ``startup`` file is requested, it should
|
tells the *tftpd* server that when the ``startup`` file is requested, it should
|
||||||
read out the actual filename from the ``dir/startup.cfg`` file.
|
read out the actual filename from the ``dir/startup.cfg`` file.
|
||||||
|
|
||||||
HTTP-based authentication
|
HTTP-based authentication
|
||||||
@ -382,15 +386,16 @@ this feature. It can be found within the ``tests/`` subdirectory. See the
|
|||||||
``config.ini`` file for this test daemon. The test daemon expects the ``pxe``
|
``config.ini`` file for this test daemon. The test daemon expects the ``pxe``
|
||||||
path to be set to ``/boot`` and the ``dhcp`` path to ``/linux``.
|
path to be set to ``/boot`` and the ``dhcp`` path to ``/linux``.
|
||||||
|
|
||||||
|
|
||||||
Sample configurations
|
Sample configurations
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Installing a Debian 6.0 machine from the official archive
|
Installing a Debian 6.0 machine from the official archive
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
As the *tftp* daemon is able to retrieve remote files using the HTTP protocol,
|
As pybootd's *tftpd* server is able to retrieve remote files using the HTTP
|
||||||
there is no need to manually download any file from a Debian mirror. The daemon
|
protocol, there is no need to manually download any file from a Debian mirror.
|
||||||
will forward all file requests to the mirror on behalf of the client being
|
The daemon will forward all file requests to the mirror on behalf of the client
|
||||||
installed.
|
being installed.
|
||||||
|
|
||||||
The ``pybootd.ini`` would contain::
|
The ``pybootd.ini`` would contain::
|
||||||
|
|
||||||
@ -400,7 +405,7 @@ The ``pybootd.ini`` would contain::
|
|||||||
; show informative and error messages only (disable verbose mode)
|
; show informative and error messages only (disable verbose mode)
|
||||||
level = info
|
level = info
|
||||||
|
|
||||||
[bootp]
|
[bootpd]
|
||||||
; do not force a full PXE boot-up cycle to accept the client
|
; do not force a full PXE boot-up cycle to accept the client
|
||||||
allow_simple_dhcp = enable
|
allow_simple_dhcp = enable
|
||||||
; First BOOTP/DHCP address to generate
|
; First BOOTP/DHCP address to generate
|
||||||
@ -410,7 +415,7 @@ The ``pybootd.ini`` would contain::
|
|||||||
; boot-up executable the client should request through TFTP
|
; boot-up executable the client should request through TFTP
|
||||||
boot_file = pxelinux.0
|
boot_file = pxelinux.0
|
||||||
|
|
||||||
[tftp]
|
[tftpd]
|
||||||
; URL to install a Debian 6.0 Intel/AMD 64-bit network installation
|
; URL to install a Debian 6.0 Intel/AMD 64-bit network installation
|
||||||
root = http://http.us.debian.org/debian/dists/squeeze/main/installer-amd64/current/images/netboot
|
root = http://http.us.debian.org/debian/dists/squeeze/main/installer-amd64/current/images/netboot
|
||||||
|
|
||||||
|
@ -31,7 +31,9 @@ from .pxed import BootpServer
|
|||||||
from .tftpd import TftpServer
|
from .tftpd import TftpServer
|
||||||
from .util import logger_factory, EasyConfigParser
|
from .util import logger_factory, EasyConfigParser
|
||||||
|
|
||||||
#pybootd: disable-msg=broad-except
|
#pylint: disable-msg=broad-except
|
||||||
|
#pylint: disable-msg=missing-docstring
|
||||||
|
#pylint: disable-msg=invalid-name
|
||||||
|
|
||||||
|
|
||||||
class BootpDaemon(Thread):
|
class BootpDaemon(Thread):
|
||||||
|
@ -2,11 +2,10 @@
|
|||||||
type = stderr
|
type = stderr
|
||||||
level = info
|
level = info
|
||||||
|
|
||||||
[bootp]
|
[bootpd]
|
||||||
address = 0.0.0.0
|
address = 0.0.0.0
|
||||||
; pool_start should be in a valid subnet
|
; pool_start should be in a valid subnet
|
||||||
; pool_start = 192.168.25.100
|
pool_start = 192.168.25.100
|
||||||
pool_start = 10.113.116.245
|
|
||||||
pool_count = 5
|
pool_count = 5
|
||||||
domain = localdomain
|
domain = localdomain
|
||||||
server_name = debug
|
server_name = debug
|
||||||
@ -14,13 +13,14 @@ boot_file = pxelinux.0
|
|||||||
lease_time = 86400
|
lease_time = 86400
|
||||||
access = mac
|
access = mac
|
||||||
allow_simple_dhcp = enable
|
allow_simple_dhcp = enable
|
||||||
dns = 10.130.0.2
|
dns = 8.8.8.8
|
||||||
set_gateway = true
|
set_gateway = true
|
||||||
; use "nc -l -u 127.0.0.1 -p 12345" to debug
|
; use "nc -l -u 127.0.0.1 -p 12345" to debug
|
||||||
; notify = 192.168.26.201:12345;192.168.26.200:12345
|
; notify = 192.168.26.201:12345;192.168.26.200:12345
|
||||||
|
|
||||||
[mac]
|
[mac]
|
||||||
00-1E-4F-C4-95-EE = enable
|
; see doc: byte separator should be defined with dash, not column
|
||||||
|
00-AA-55-12-34-56 = enable
|
||||||
|
|
||||||
[uuid]
|
[uuid]
|
||||||
12345678-abcd-ef00-1111-abcdefabcdef = enable
|
12345678-abcd-ef00-1111-abcdefabcdef = enable
|
||||||
@ -32,10 +32,10 @@ pxe = boot
|
|||||||
dhcp = linux
|
dhcp = linux
|
||||||
always_check = disable
|
always_check = disable
|
||||||
|
|
||||||
[tftp]
|
[tftpd]
|
||||||
;address = (use address from bootpd)
|
;address = (use address from bootpd)
|
||||||
;root = ./images
|
root = ./images
|
||||||
root = http://http.us.debian.org/debian/dists/squeeze/main/installer-amd64/current/images/netboot
|
;root = http://http.us.debian.org/debian/dists/squeeze/main/installer-amd64/current/images/netboot
|
||||||
|
|
||||||
[filters]
|
[filters]
|
||||||
;pxelinux.cfg/* = pybootd/etc/pxe.cfg
|
;pxelinux.cfg/* = pybootd/etc/pxe.cfg
|
||||||
|
@ -182,6 +182,8 @@ class BootpServer:
|
|||||||
ACCESS_REMOTE = ['http'] # Access modes, remotely retrieved
|
ACCESS_REMOTE = ['http'] # Access modes, remotely retrieved
|
||||||
(ST_IDLE, ST_PXE, ST_DHCP) = range(3) # Current state
|
(ST_IDLE, ST_PXE, ST_DHCP) = range(3) # Current state
|
||||||
|
|
||||||
|
BOOTP_SECTION = 'bootpd'
|
||||||
|
|
||||||
def __init__(self, logger, config):
|
def __init__(self, logger, config):
|
||||||
self.sock = []
|
self.sock = []
|
||||||
self.log = logger
|
self.log = logger
|
||||||
@ -190,16 +192,15 @@ class BootpServer:
|
|||||||
self.ippool = {} # key MAC address string, value assigned IP string
|
self.ippool = {} # key MAC address string, value assigned IP string
|
||||||
self.filepool = {} # key IP string, value pathname
|
self.filepool = {} # key IP string, value pathname
|
||||||
self.states = {} # key MAC address string, value client state
|
self.states = {} # key MAC address string, value client state
|
||||||
self.bootp_section = 'bootp'
|
self.pool_start = self.config.get(self.BOOTP_SECTION, 'pool_start')
|
||||||
self.pool_start = self.config.get(self.bootp_section, 'pool_start')
|
|
||||||
if not self.pool_start:
|
if not self.pool_start:
|
||||||
raise BootpError('Missing pool_start definition')
|
raise BootpError('Missing pool_start definition')
|
||||||
self.pool_count = int(self.config.get(self.bootp_section,
|
self.pool_count = int(self.config.get(self.BOOTP_SECTION,
|
||||||
'pool_count', '10'))
|
'pool_count', '10'))
|
||||||
|
|
||||||
self.netconfig = get_iface_config(self.pool_start)
|
self.netconfig = get_iface_config(self.pool_start)
|
||||||
if not self.netconfig:
|
if not self.netconfig:
|
||||||
host = self.config.get(self.bootp_section, 'address', '0.0.0.0')
|
host = self.config.get(self.BOOTP_SECTION, 'address', '0.0.0.0')
|
||||||
self.netconfig = get_iface_config(host)
|
self.netconfig = get_iface_config(host)
|
||||||
if not self.netconfig:
|
if not self.netconfig:
|
||||||
# the available networks on the host may not match the config...
|
# the available networks on the host may not match the config...
|
||||||
@ -208,7 +209,7 @@ class BootpServer:
|
|||||||
keys = sorted(self.netconfig.keys())
|
keys = sorted(self.netconfig.keys())
|
||||||
self.log.info('Using %s' % ', '.join(map(
|
self.log.info('Using %s' % ', '.join(map(
|
||||||
':'.join, zip(keys, [self.netconfig[k] for k in keys]))))
|
':'.join, zip(keys, [self.netconfig[k] for k in keys]))))
|
||||||
nlist = self.config.get(self.bootp_section, 'notify')
|
nlist = self.config.get(self.BOOTP_SECTION, 'notify')
|
||||||
self.notify = []
|
self.notify = []
|
||||||
if nlist:
|
if nlist:
|
||||||
try:
|
try:
|
||||||
@ -218,7 +219,7 @@ class BootpServer:
|
|||||||
self.notify.append((n[0], int(n[1])))
|
self.notify.append((n[0], int(n[1])))
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
raise BootpError('Invalid notification URL: %s' % exc)
|
raise BootpError('Invalid notification URL: %s' % exc)
|
||||||
access = self.config.get(self.bootp_section, 'access')
|
access = self.config.get(self.BOOTP_SECTION, 'access')
|
||||||
if not access:
|
if not access:
|
||||||
self.acl = None
|
self.acl = None
|
||||||
else:
|
else:
|
||||||
@ -257,8 +258,8 @@ class BootpServer:
|
|||||||
return self.netconfig
|
return self.netconfig
|
||||||
|
|
||||||
def bind(self):
|
def bind(self):
|
||||||
host = self.config.get(self.bootp_section, 'address', '0.0.0.0')
|
host = self.config.get(self.BOOTP_SECTION, 'address', '0.0.0.0')
|
||||||
port = self.config.get(self.bootp_section, 'port',
|
port = self.config.get(self.BOOTP_SECTION, 'port',
|
||||||
str(BOOTP_PORT_REQUEST))
|
str(BOOTP_PORT_REQUEST))
|
||||||
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
|
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
|
||||||
sock.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
|
sock.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
|
||||||
@ -398,8 +399,8 @@ class BootpServer:
|
|||||||
if newstate == self.ST_IDLE:
|
if newstate == self.ST_IDLE:
|
||||||
sdhcp = 'allow_simple_dhcp'
|
sdhcp = 'allow_simple_dhcp'
|
||||||
simple_dhcp = \
|
simple_dhcp = \
|
||||||
self.config.has_option(self.bootp_section, sdhcp) and \
|
self.config.has_option(self.BOOTP_SECTION, sdhcp) and \
|
||||||
to_bool(self.config.get(self.bootp_section, sdhcp))
|
to_bool(self.config.get(self.BOOTP_SECTION, sdhcp))
|
||||||
if not simple_dhcp:
|
if not simple_dhcp:
|
||||||
self.log.info('Request from %s ignored (idle state)' % mac_str)
|
self.log.info('Request from %s ignored (idle state)' % mac_str)
|
||||||
return
|
return
|
||||||
@ -497,7 +498,7 @@ class BootpServer:
|
|||||||
raise BootpError('No more IP available in definined pool')
|
raise BootpError('No more IP available in definined pool')
|
||||||
|
|
||||||
mask = iptoint(self.config.get(
|
mask = iptoint(self.config.get(
|
||||||
self.bootp_section, 'netmask', self.netconfig['mask']))
|
self.BOOTP_SECTION, 'netmask', self.netconfig['mask']))
|
||||||
reply_broadcast = iptoint(ip) & mask
|
reply_broadcast = iptoint(ip) & mask
|
||||||
reply_broadcast |= (~mask) & ((1 << 32)-1)
|
reply_broadcast |= (~mask) & ((1 << 32)-1)
|
||||||
buf[BOOTP_YIADDR] = inet_aton(ip)
|
buf[BOOTP_YIADDR] = inet_aton(ip)
|
||||||
@ -517,12 +518,12 @@ class BootpServer:
|
|||||||
buf[BOOTP_SIADDR] = inet_aton(server_addr)
|
buf[BOOTP_SIADDR] = inet_aton(server_addr)
|
||||||
# sname
|
# sname
|
||||||
buf[BOOTP_SNAME] = \
|
buf[BOOTP_SNAME] = \
|
||||||
'.'.join([self.config.get(self.bootp_section,
|
'.'.join([self.config.get(self.BOOTP_SECTION,
|
||||||
'servername', 'unknown'),
|
'servername', 'unknown'),
|
||||||
self.config.get(self.bootp_section,
|
self.config.get(self.BOOTP_SECTION,
|
||||||
'domain', 'localdomain')]).encode()
|
'domain', 'localdomain')]).encode()
|
||||||
# file
|
# file
|
||||||
buf[BOOTP_FILE] = self.config.get(self.bootp_section,
|
buf[BOOTP_FILE] = self.config.get(self.BOOTP_SECTION,
|
||||||
'boot_file', '\x00').encode()
|
'boot_file', '\x00').encode()
|
||||||
|
|
||||||
if not dhcp_msg_type:
|
if not dhcp_msg_type:
|
||||||
@ -573,18 +574,18 @@ class BootpServer:
|
|||||||
pkt += spack('!BB4s', DHCP_SERVER, 4, server)
|
pkt += spack('!BB4s', DHCP_SERVER, 4, server)
|
||||||
|
|
||||||
mask = inet_aton(self.config.get(
|
mask = inet_aton(self.config.get(
|
||||||
self.bootp_section, 'netmask', self.netconfig['mask']))
|
self.BOOTP_SECTION, 'netmask', self.netconfig['mask']))
|
||||||
|
|
||||||
pkt += spack('!BB4s', DHCP_IP_MASK, 4, mask)
|
pkt += spack('!BB4s', DHCP_IP_MASK, 4, mask)
|
||||||
|
|
||||||
gateway_addr = self.config.get(self.bootp_section, 'gateway', '')
|
gateway_addr = self.config.get(self.BOOTP_SECTION, 'gateway', '')
|
||||||
if gateway_addr:
|
if gateway_addr:
|
||||||
gateway = inet_aton(gateway_addr)
|
gateway = inet_aton(gateway_addr)
|
||||||
else:
|
else:
|
||||||
gateway = server
|
gateway = server
|
||||||
pkt += spack('!BB4s', DHCP_IP_GATEWAY, 4, gateway)
|
pkt += spack('!BB4s', DHCP_IP_GATEWAY, 4, gateway)
|
||||||
|
|
||||||
dns = self.config.get(self.bootp_section,
|
dns = self.config.get(self.BOOTP_SECTION,
|
||||||
'dns', None)
|
'dns', None)
|
||||||
if dns:
|
if dns:
|
||||||
if dns.lower() == 'auto':
|
if dns.lower() == 'auto':
|
||||||
@ -595,7 +596,7 @@ class BootpServer:
|
|||||||
dns_ip = inet_aton(dns_str)
|
dns_ip = inet_aton(dns_str)
|
||||||
pkt += spack('!BB4s', DHCP_IP_DNS, 4, dns_ip)
|
pkt += spack('!BB4s', DHCP_IP_DNS, 4, dns_ip)
|
||||||
pkt += spack('!BBI', DHCP_LEASE_TIME, 4,
|
pkt += spack('!BBI', DHCP_LEASE_TIME, 4,
|
||||||
int(self.config.get(self.bootp_section,
|
int(self.config.get(self.BOOTP_SECTION,
|
||||||
'lease_time',
|
'lease_time',
|
||||||
str(24*3600))))
|
str(24*3600))))
|
||||||
pkt += spack('!BB', DHCP_END, 0)
|
pkt += spack('!BB', DHCP_END, 0)
|
||||||
|
@ -404,25 +404,28 @@ class TftpServer:
|
|||||||
Each request is handled in its own thread
|
Each request is handled in its own thread
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
TFTP_SECTION = 'tftpd'
|
||||||
|
|
||||||
def __init__(self, logger, config, bootpd=None):
|
def __init__(self, logger, config, bootpd=None):
|
||||||
self.log = logger
|
self.log = logger
|
||||||
self.config = config
|
self.config = config
|
||||||
self.sock = []
|
self.sock = []
|
||||||
self.bootpd = bootpd
|
self.bootpd = bootpd
|
||||||
self.blocksize = int(self.config.get('tftp', 'blocksize', '512'))
|
self.blocksize = int(self.config.get(self.TFTP_SECTION, 'blocksize',
|
||||||
self.timeout = float(self.config.get('tftp', 'timeout', '2.0'))
|
'512'))
|
||||||
self.retry = int(self.config.get('tftp', 'blocksize', '5'))
|
self.timeout = float(self.config.get(self.TFTP_SECTION, 'timeout', '2.0'))
|
||||||
self.root = self.config.get('tftp', 'root', os.getcwd())
|
self.retry = int(self.config.get(self.TFTP_SECTION, 'blocksize', '5'))
|
||||||
|
self.root = self.config.get(self.TFTP_SECTION, 'root', os.getcwd())
|
||||||
self.fcre, self.filepatterns = self.get_file_filters()
|
self.fcre, self.filepatterns = self.get_file_filters()
|
||||||
self.genfilecre = recompile(r'\[(?P<name>[\w\.\-]+)\]')
|
self.genfilecre = recompile(r'\[(?P<name>[\w\.\-]+)\]')
|
||||||
|
|
||||||
def bind(self):
|
def bind(self):
|
||||||
netconfig = self.bootpd and self.bootpd.get_netconfig()
|
netconfig = self.bootpd and self.bootpd.get_netconfig()
|
||||||
host = self.config.get('tftp', 'address',
|
host = self.config.get(self.TFTP_SECTION, 'address',
|
||||||
netconfig and netconfig['server'])
|
netconfig and netconfig['server'])
|
||||||
if not host:
|
if not host:
|
||||||
raise TftpError(TftpError.NO_SUCH_USER, 'TFTP address no defined')
|
raise TftpError(TftpError.NO_SUCH_USER, 'TFTP address no defined')
|
||||||
port = int(self.config.get('tftp', 'port', str(TFTP_PORT)))
|
port = int(self.config.get(self.TFTP_SECTION, 'port', str(TFTP_PORT)))
|
||||||
sock = socket(AF_INET, SOCK_DGRAM)
|
sock = socket(AF_INET, SOCK_DGRAM)
|
||||||
self.sock.append(sock)
|
self.sock.append(sock)
|
||||||
sock.bind((host, port))
|
sock.bind((host, port))
|
||||||
@ -433,7 +436,7 @@ class TftpServer:
|
|||||||
if not self.bootpd.is_alive():
|
if not self.bootpd.is_alive():
|
||||||
self.log.info('Bootp daemon is dead, exiting')
|
self.log.info('Bootp daemon is dead, exiting')
|
||||||
break
|
break
|
||||||
r, w, e = select(self.sock, [], self.sock)
|
r = select(self.sock, [], self.sock)[0]
|
||||||
for sock in r:
|
for sock in r:
|
||||||
data, addr = sock.recvfrom(516)
|
data, addr = sock.recvfrom(516)
|
||||||
tc = TftpConnection(self)
|
tc = TftpConnection(self)
|
||||||
|
Loading…
Reference in New Issue
Block a user