source: trunk/src/pxeconfigd.py @ 187

Last change on this file since 187 was 186, checked in by bas, 14 years ago

Added mac address support for environments that have dynamic ip's. Depended on arp command

  • Property keywords set to Id
  • Property svn:executable set to *
  • Property svn:keywords set to Id
File size: 4.6 KB
Line 
1# Copyright (C) 2002
2#
3# This file is part of the pxeconfig utils
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the
7# Free Software Foundation; either version 2, or (at your option) any
8# later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
18#
19# SVN info
20#  $Id: pxeconfigd.py 186 2010-10-28 14:04:25Z bas $
21"""
22Author: Bas van der Vlies <basv@sara.nl>
23Date  : 12 February 2002
24Desc. : This script is used to control how a node is booted with PXE
25        enabled network cards. The node boots and fetch a pxe
26        config file which tells how the node must boot. This daemon
27        enables a client to remove his/here pxe config file. With the
28        next boot it will use the default one.
29
30        command line option:
31          -V/--version
32            Prints the version number and exits
33         
34        Note:
35          This server can ONLY be started from inetd.
36"""
37import time
38import socket
39import sys
40import os
41import string
42import syslog
43import getopt
44
45# PXE modules
46from pxe_global import *
47
48# DEBUG
49#
50DEBUG=1
51
52# Some Global Constants
53#
54BUFSIZE=4096
55STDIN=0
56STDOUT=1
57SHORTOPT_LIST='V'
58LONGOPT_LIST=['version']
59
60PXE_CONF_DIR = '/tftpboot/pxelinux.cfg'
61VERSION = '3.1.0'
62
63# Give the current time
64#
65def now():
66    return time.ctime(time.time())
67
68
69def remove_link(ip, arp_cmd):
70        """
71        This removes the pxe config filename for the host that is connected:
72                ip      : ip address of the client host
73                arp_cmd : For Dynamic ips, look up the mac address via arp
74        """
75
76        ## translate ip address ---> hex address
77        #
78        d = string.split(ip, '.')
79        haddr = '%02X%02X%02X%02X' %(int(d[0]), int(d[1]), int(d[2]), int(d[3])) 
80
81        file = os.path.join(PXE_CONF_DIR, haddr)
82
83        if not os.path.exists(file): 
84
85                ##
86                # No ARP command set, just return
87                #
88                if not arp_cmd:
89                        return
90
91                else:
92                        ##
93                        #  arp -n 192.168.146.112
94                        # Address          HWtype  HWaddress           Flags Mask Iface
95                        # 192.168.146.112  ether   00:23:ae:fd:cf:74   C          vlan133
96
97                        cmd = '%s %s' %(arp_cmd, ip)
98                        lines = os.popen(cmd).readlines()
99                        for line in lines:
100                                if line.startswith(ip):
101                                        t = line.split()
102                                        mac_addr = t[2] 
103                                        haddr = '01-%s' %(mac_addr.replace(':', '-').lower())
104                                        file = os.path.join(PXE_CONF_DIR, haddr) 
105                                        if not os.path.exists(file): 
106                                                return
107
108        if DEBUG:
109                print 'file = %s' %file
110
111        if os.path.islink(file): 
112                try:
113                        os.unlink(file)
114                        syslog.openlog("pxeconfigd")
115                        syslog.syslog(syslog.LOG_INFO, file)
116                        syslog.closelog()
117                except OSError:
118                        err_msg = "No permission at directory: %s" %PXE_CONF_DIR
119                        os.write(STDOUT, err_msg)
120                        sys.exit(1)
121
122
123# This function handles the client connection. It closes
124# the connection if there is no data
125#
126def handleConnection(settings):
127        """
128        Determines which host connects to the server
129        """ 
130       
131        # Determine client address
132        #
133        try:
134                client_addr = socket.fromfd(sys.stdin.fileno(), socket.AF_INET, 
135                          socket.SOCK_STREAM)
136                client_ip = client_addr.getpeername()[0] 
137        except socket.error, detail:
138                error =  "pxeconfigd can only be started from inetd!!!"
139                raise PxeConfig, error
140               
141       
142        if DEBUG:
143                print 'ip = %s, hex = %s' %(client_ip, client_haddr) 
144
145        try:
146                cmd = '%s %s' %(settings['daemon_script_hook'], client_ip)
147                print cmd
148                os.system(cmd)
149        except KeyError:
150                pass
151
152        try:
153                arp_cmd = settings['arp_command']
154        except KeyError:
155                arp_cmd = None
156
157        remove_link(client_ip, arp_cmd)
158        sys.exit(0)
159
160def check_args(argv, settings):
161        """
162        Must we use another directory for the PXE configuration
163        """
164        global PXE_CONF_DIR
165       
166        try:
167                opts, args = getopt.getopt(argv[1:], SHORTOPT_LIST, LONGOPT_LIST)
168        except getopt.error, detail:
169                print __doc__
170                print detail
171                sys.exit(1) 
172               
173        for opt, value in opts:
174                if opt in ['-V', '--version']:
175                        print VERSION
176                        sys.exit(0)
177
178        try:
179                PXE_CONF_DIR = settings['pxe_config_dir']
180        except KeyError:
181                pass 
182               
183        PXE_CONF_DIR = os.path.realpath(PXE_CONF_DIR) 
184        if not os.path.isdir(PXE_CONF_DIR):
185                error =  'pxeconfig directory: %s does not exists' %(PXE_CONF_DIR)
186                raise PxeConfig, error
187
188def server():
189  """Start the daemon
190  """
191  parser_config, default_settings = ReadConfig()
192  check_args(sys.argv, default_settings)
193  handleConnection(default_settings)
194
195if __name__ == '__main__':
196  server()
Note: See TracBrowser for help on using the repository browser.