# Copyright (C) 2002 # # This file is part of the pxeconfig utils # # This program 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 2, or (at your option) any # later version. # # This program 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 this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # SVN info # $Id: pxeconfigd.py 206 2012-12-18 11:53:42Z bas $ """ Author: Bas van der Vlies Date : 12 February 2002 Desc. : This script is used to control how a node is booted with PXE enabled network cards. The node boots and fetch a pxe config file which tells how the node must boot. This daemon enables a client to remove his/here pxe config file. With the next boot it will use the default one. command line option: -V/--version Prints the version number and exits Note: This server can ONLY be started from inetd/xinetd. """ import time import socket import sys import os import string import syslog import getopt # PXE modules from pxe_global import * # DEBUG # DEBUG=1 # Some Global Constants # BUFSIZE=4096 STDIN=0 STDOUT=1 SHORTOPT_LIST='V' LONGOPT_LIST=['version'] PXE_CONF_DIR = '/tftpboot/pxelinux.cfg' VERSION = '4.2.0' # Give the current time # def now(): return time.ctime(time.time()) def remove_link(ip, arp_cmd): """ This removes the pxe config filename for the host that is connected: ip : ip address of the client host arp_cmd : For Dynamic ips, look up the mac address via arp """ ## translate ip address ---> hex address # d = string.split(ip, '.') haddr = '%02X%02X%02X%02X' %(int(d[0]), int(d[1]), int(d[2]), int(d[3])) file = os.path.join(PXE_CONF_DIR, haddr) if DEBUG: print file if not os.path.exists(file): ## # No ARP command set, just return # if not arp_cmd: return else: ## # arp -n 192.168.146.112 # Address HWtype HWaddress Flags Mask Iface # 192.168.146.112 ether 00:23:ae:fd:cf:74 C vlan133 cmd = '%s %s' %(arp_cmd, ip) lines = os.popen(cmd).readlines() for line in lines: if line.startswith(ip): t = line.split() mac_addr = t[2] haddr = '01-%s' %(mac_addr.replace(':', '-').lower()) file = os.path.join(PXE_CONF_DIR, haddr) if DEBUG: print file if not os.path.exists(file): return if DEBUG: print 'file = %s' %file if os.path.islink(file): try: os.unlink(file) syslog.openlog("pxeconfigd") syslog.syslog(syslog.LOG_INFO, file) syslog.closelog() except OSError: err_msg = "No permission at directory: %s" %PXE_CONF_DIR os.write(STDOUT, err_msg) sys.exit(1) # This function handles the client connection. It closes # the connection if there is no data # def handleConnection(settings): """ Determines which host connects to the server """ # Determine client address # try: client_addr = socket.fromfd(sys.stdin.fileno(), socket.AF_INET, socket.SOCK_STREAM) client_ip = client_addr.getpeername()[0] except socket.error, detail: error = "pxeconfigd can only be started from inetd!!!" raise PxeConfig, error if DEBUG: print 'ip = %s' %(client_ip) try: cmd = '%s %s' %(settings['daemon_script_hook'], client_ip) print cmd os.system(cmd) except KeyError: pass try: arp_cmd = settings['arp_command'] except KeyError: arp_cmd = None remove_link(client_ip, arp_cmd) sys.exit(0) def check_args(argv, settings): """ Must we use another directory for the PXE configuration """ global PXE_CONF_DIR try: opts, args = getopt.getopt(argv[1:], SHORTOPT_LIST, LONGOPT_LIST) except getopt.error, detail: print __doc__ print detail sys.exit(1) for opt, value in opts: if opt in ['-V', '--version']: print VERSION sys.exit(0) try: PXE_CONF_DIR = settings['pxe_config_dir'] except KeyError: pass PXE_CONF_DIR = os.path.realpath(PXE_CONF_DIR) if not os.path.isdir(PXE_CONF_DIR): error = 'pxeconfig directory: %s does not exists' %(PXE_CONF_DIR) raise PxeConfig, error def server(): """Start the daemon """ parser_config, default_settings = ReadConfig() check_args(sys.argv, default_settings) handleConnection(default_settings) if __name__ == '__main__': server()