-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpxeserver.py
executable file
·111 lines (93 loc) · 3.88 KB
/
pxeserver.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#!/usr/bin/env python
# coding=utf-8
# Author: David Anderson
# dave@natulte.net
#
# This file is part of pTFTPd.
#
# pTFTPd is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pTFTPd is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with pTFTPd. If not, see <http://www.gnu.org/licenses/>.
"""PXE Server.
This program offers a streamlined combination of ptftpd.py and
dhcpd.py in a single executable. With both daemons running side by
side, the amount of configuration required to get a PXE boot system
working is laughably small: specify the interface, the directory to
serve over TFTP and the name of the PXE boot file, and you're all set.
"""
import errno
import logging
import socket
import sys
import threading
import notify
import tftpserver
import dhcpserver
l = notify.getLogger('pxed')
class DHCPThread(threading.Thread):
def __init__(self, iface, bootfile, router):
threading.Thread.__init__(self)
self.setDaemon(True)
self.server = dhcpserver.DHCPServer(iface, bootfile, router=router)
def run(self):
self.server.serve_forever()
def main():
import optparse
usage = "Usage: %prog [options] <iface> <TFTP root> <PXE boot filename>"
parser = optparse.OptionParser(usage=usage)
parser.add_option("-r", "--rfc1350", dest="strict_rfc1350",
action="store_true", default=False,
help="Run in strict RFC1350 compliance mode, "
"with no extensions")
parser.add_option("-g", "--gateway", dest="router", default=None,
help="The IP address of the default gateway "
"(by default, the IP of the PXE server)")
parser.add_option("-v", "--verbose", dest="loglevel", action="store_const",
const=logging.INFO, help="Output information messages",
default=logging.WARNING)
parser.add_option("-D", "--debug", dest="loglevel", action="store_const",
const=logging.DEBUG, help="Output debugging information")
(options, args) = parser.parse_args()
if len(args) != 3:
parser.print_help()
return 1
iface, root, bootfile = args
# Setup notification logging
notify.StreamEngine.install(l, stream=sys.stdout,
loglevel=options.loglevel,
fmt='%(levelname)s(%(name)s): %(message)s')
notify.StreamEngine.install(dhcpserver.l, stream=sys.stdout,
loglevel=options.loglevel,
fmt='%(levelname)s(%(name)s): %(message)s')
notify.StreamEngine.install(tftpserver.l, stream=sys.stdout,
loglevel=options.loglevel,
fmt='%(levelname)s(%(name)s): %(message)s')
try:
dhcp = DHCPThread(iface, bootfile, options.router)
tftp = tftpserver.TFTPServer(iface, root,
strict_rfc1350=options.strict_rfc1350)
except tftpserver.TFTPServerConfigurationError as e:
sys.stderr.write('TFTP server configuration error: %s!\n' %
e.args)
return 1
except socket.error as e:
sys.stderr.write('Socket error (%s): %s!\n' %
(errno.errorcode[e.args[0]], e.args[1]))
return 1
dhcp.start()
tftp.serve_forever()
return 0
if __name__ == '__main__':
try:
sys.exit(main())
except KeyboardInterrupt:
pass