Skip to content

Commit

Permalink
Refactor:
Browse files Browse the repository at this point in the history
* move constants to a separate file
* create class for handling messages and move to separate file
* create classs for handling lease and move to separate file
* create class for handling external script and move to separate file
* move timer related functions to separate file
* rename main class to DHCPCAPFSM
* add timeout methods
  • Loading branch information
juga0 committed May 17, 2017
1 parent 47abf9e commit 183d277
Show file tree
Hide file tree
Showing 14 changed files with 1,137 additions and 1,021 deletions.
64 changes: 64 additions & 0 deletions dhcpcanon/clientscript.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#
""""""
from __future__ import unicode_literals
import os
import logging
import attr
import subprocess

from constants import STATES2REASONS

logger = logging.getLogger('dhcpcanon')


@attr.s
class ClientScript(object):
"""Simulates the behaviour of isc-dhcp client-script or
Network Manager nm-dhcp-helper.
"""
scriptname = attr.ib(default=None)
env = attr.ib(default=attr.Factory(dict))

def script_init(self, lease, state, prefix='', medium=''):
logger.debug('script init with state %s', state)
if type(state) == int:
reason = STATES2REASONS[state]
else:
reason = state
self.env['reason'] = reason
# FIXME: what is medium?
self.env['medium'] = medium
self.env['client'] = 'dhcpcanon'
self.env['pid'] = str(os.getpid())
self.env['interface'] = str(lease.interface)
self.env['ip_address'] = str(lease.address)
self.env['subnet_mask'] = lease.subnet_mask
self.env['network_number'] = str(lease.network)
self.env['broadcast_address'] = lease.broadcast_address
self.env['domain_name_servers'] = lease.name_server
self.env['routers'] = lease.router
self.env['dhcp_server_identifier'] = str(lease.server_address)
self.env['next_server'] = lease.next_server
self.env['domain_name'] = lease.domain
# FIXME: what is expiry?
self.env['expiry'] = str(lease.lease_time)
self.env['dhcp_lease_time'] = str(lease.lease_time)
self.env['dhcp_renewal_time'] = str(lease.renewal_time)
self.env['dhcp_rebinding_time'] = str(lease.rebinding_time)
# logger.debug('env %s', self.env)

def script_go(self, scriptname=None, env=None):
scriptname = self.scriptname or scriptname
env = self.env or env
envstr = "\n".join(["%s='%s'" % (k, v) for (k, v) in
env.items()])
logger.debug('calling script %s', scriptname)
# with env %s', scriptname,
# envstr)
# os.execve(scriptname, [scriptname], clientenv)
p = subprocess.Popen([scriptname], shell=False,
stdin=None, stdout=None, stderr=None,
close_fds=True, env=env)
# FIXME: what to do with p?
return p
3 changes: 2 additions & 1 deletion dhcpcanon/conf_log.py → dhcpcanon/conflog.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
'disable_existing_loggers': True,
'formatters': {
'verbose': {
'format': '%(levelname)s %(module)s[%(process)d.%(thread)d]'\
'format': '%(asctime)s %(levelname)s'\
'%(module)s[%(process)d.]'\
' %(filename)s:%(lineno)s -'\
' %(funcName)s - %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S'
Expand Down
134 changes: 134 additions & 0 deletions dhcpcanon/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# -*- coding: utf-8 -*-
# vim:ts=4:sw=4:expandtab 2

# Copyright 2016 juga <juga@riseup.net>

# This file is part of dhcpcanon.
#
# dhcpcanon 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.
#
# dhcpcanon 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 dhcpcanon. If not, see <http://www.gnu.org/licenses/>.

"""."""
import logging

logger = logging.getLogger(__name__)


DT_PRINT_FORMAT = '%y-%m-%d %H:%M:%S %Z'

# client
##########
BROADCAST_MAC = 'ff:ff:ff:ff:ff:ff'
META_MAC = '00:00:00:00:00:00'
BROADCAST_ADDR = '255.255.255.255'
META_ADDR = '0.0.0.0'
CLIENT_PORT = 68
SERVER_PORT = 67

# DHCP timers
##########
LEASE_TIME = 1209600 # 14 DAYS
RENEWING_TIME = 604800 # 7 DAYS
REBINDING_TIME = 1058400 # 12 DAYS
DELAY_SELECTING = 10
TIMEOUT_SELECTING = 60
TIMEOUT_REQUESTING = 60
TIMEOUT_REQUEST_RENEWING = 226800
TIMEOUT_REQUEST_REBINDING = 75600

MAX_DELAY_SELECTING = 10
RENEW_PERC = 0.5
REBIND_PERC = 0.875
# FIXME:
# MAX_TIMEOUT =
# FIXME: microseconds per unix second?
USEC_PER_SECS = 1000000

# DHCP number packet retransmissions
MAX_ATTEMPTS_DISCOVER = 5
MAX_OFFERS_COLLECTED = 1
MAX_ATTEMPTS_REQUEST = 5

# DHCP packet
##############
DHCP_OFFER_OPTIONS = [
'server_id', 'subnet_mask', 'broadcast_address',
'router', 'domain', 'name_server', 'lease_time', 'renewal_time',
'rebinding_time']

# NOTE: 3.6. The choice of option numbers and the specific ordering of option
# numbers in the PRL can be used to fingerprint the client
# SHOULD only request a
# minimal number of options in the PRL and SHOULD also randomly shuffle
# the ordering of option codes in the PRL
# PARAM_REQ_LIST = '\x01\x03\x06\x0fw\xfc'# \x1c3
PARAM_REQ_LIST = '\x01\x1c\x02\x03\x0f\x06\x77\x0c\x2c\x2f\x1a\x79\x2a'
XID_MIN = 1
XID_MAX = 900000000

# DHCP FSM
#############
STATE_ERROR = -1
STATE_PREINIT = 0
STATE_INIT = 1
STATE_SELECTING = 2
STATE_REQUESTING = 3
STATE_BOUND = 4
STATE_RENEWING = 5
STATE_REBINDING = 6
STATE_END = 7

STATES2NAMES = {
STATE_ERROR: 'ERROR',
STATE_PREINIT: 'PREINIT',
STATE_INIT: 'INIT',
STATE_SELECTING: 'SELECTING',
STATE_REQUESTING: 'REQUESTING',
STATE_BOUND: 'BOUND',
STATE_RENEWING: 'RENEWING',
STATE_REBINDING: 'REBINDING',
STATE_END: 'END',
}

# NM integration
#####################
REASONS_NM = [
'bound', 'renew', 'rebind',
'timeout',
'nak', 'expire',
'end',
'fail',
'abend'
]

STATES2REASONS = {
STATE_PREINIT: 'PREINIT',
STATE_INIT: 'INIT',
STATE_BOUND: 'BOUND',
STATE_END: 'END',
STATE_REBINDING: 'REBIND',
STATE_RENEWING: 'RENEW',
# "EXPIRE"
STATE_ERROR: "TIMEOUT",
# "FAIL"
# "STOP"
}

# similar to systemd
DHCP_EVENTS = {
'STOP': 0,
'IP_ACQUIRE': 1,
'IP_CHANGE': 2,
'EXPIRED': 3,
'RENEW': 4,
}

0 comments on commit 183d277

Please sign in to comment.