pppoe.py 8 KB
Newer Older
1 2
#!/usr/bin/python
# -*- coding: utf-8 -*-
3 4 5 6 7 8 9 10 11 12
#
# Copyright (C) 2005, TUBITAK/UEKAE
#
# 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 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.
#
13 14 15 16 17

import popen2
import os

class pppoe:
18
    """ Functions to configure and run PPP over Ethernet connections  """
19

20
    tmpl_pppoe_conf = """
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
#***********************************************************************
#
# /etc/ppp/pppoe.conf
#
# Configuration file for rp-pppoe.
#
# NOTE: This file is used by the adsl-start, adsl-stop, adsl-connect and
#       adsl-status shell scripts.  It is *not* used in any way by the
#       "pppoe" executable.
#
#***********************************************************************

# When you configure a variable, DO NOT leave spaces around the "=" sign.

# Ethernet card connected to ADSL modem
ETH=\"%s\"

# ADSL user name.  You may have to supply "@provider.com"  Sympatico
# users in Canada do need to include "@sympatico.ca"
# Sympatico uses PAP authentication.  Make sure /etc/ppp/pap-secrets
# contains the right username/password combination.
# For Magma, use xxyyzz@magma.ca
USER=\"%s\"

# Bring link up on demand?  Default is to leave link up all the time.
# If you want the link to come up on demand, set DEMAND to a number indicating
# the idle time after which the link is brought down.
DEMAND=no
#DEMAND=300

# DNS type: SERVER=obtain from server; SPECIFY=use DNS1 and DNS2;
# NOCHANGE=do not adjust.
53
DNSTYPE=COMAR
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 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154

# Obtain DNS server addresses from the peer (recent versions of pppd only)
# In old config files, this used to be called USEPEERDNS.  Changed to
# PEERDNS for better Red Hat compatibility
PEERDNS=yes

DNS1=
DNS2=

# Make the PPPoE connection your default route.  Set to
# DEFAULTROUTE=no if you don't want this.
DEFAULTROUTE=yes

### ONLY TOUCH THE FOLLOWING SETTINGS IF YOU'RE AN EXPERT

# How long adsl-start waits for a new PPP interface to appear before
# concluding something went wrong.  If you use 0, then adsl-start
# exits immediately with a successful status and does not wait for the
# link to come up.  Time is in seconds.
#
# WARNING WARNING WARNING:
#
# If you are using rp-pppoe on a physically-inaccessible host, set
# CONNECT_TIMEOUT to 0.  This makes SURE that the machine keeps trying
# to connect forever after adsl-start is called.  Otherwise, it will
# give out after CONNECT_TIMEOUT seconds and will not attempt to
# connect again, making it impossible to reach.
CONNECT_TIMEOUT=30

# How often in seconds adsl-start polls to check if link is up
CONNECT_POLL=2

# Specific desired AC Name
ACNAME=

# Specific desired service name
SERVICENAME=

# Character to echo at each poll.  Use PING="" if you don't want
# anything echoed
PING="."

# File where the adsl-connect script writes its process-ID.
# Three files are actually used:
#   $PIDFILE       contains PID of adsl-connect script
#   $PIDFILE.pppoe contains PID of pppoe process
#   $PIDFILE.pppd  contains PID of pppd process
#
# PIDFILE="/var/run/$CF_BASE-adsl.pid"
PIDFILE="/var/run/adsl.pid"

# Do you want to use synchronous PPP?  "yes" or "no".  "yes" is much
# easier on CPU usage, but may not work for you.  It is safer to use
# "no", but you may want to experiment with "yes".  "yes" is generally
# safe on Linux machines with the n_hdlc line discipline; unsafe on others.
SYNCHRONOUS=no

# Do you want to clamp the MSS?  Here's how to decide:
# - If you have only a SINGLE computer connected to the ADSL modem, choose
#   "no".
# - If you have a computer acting as a gateway for a LAN, choose "1412".
#   The setting of 1412 is safe for either setup, but uses slightly more
#   CPU power.
CLAMPMSS=1412
#CLAMPMSS=no

# LCP echo interval and failure count.
LCP_INTERVAL=20
LCP_FAILURE=3

# PPPOE_TIMEOUT should be about 4*LCP_INTERVAL
PPPOE_TIMEOUT=80

# Firewalling: One of NONE, STANDALONE or MASQUERADE
FIREWALL=NONE

# Linux kernel-mode plugin for pppd.  If you want to try the kernel-mode
# plugin, use LINUX_PLUGIN=rp-pppoe.so
LINUX_PLUGIN=

# Any extra arguments to pass to pppoe.  Normally, use a blank string
# like this:
PPPOE_EXTRA=""

# Rumour has it that "Citizen's Communications" with a 3Com
# HomeConnect ADSL Modem DualLink requires these extra options:
# PPPOE_EXTRA="-f 3c12:3c13 -S ISP"

# Any extra arguments to pass to pppd.  Normally, use a blank string
# like this:
PPPD_EXTRA=""


########## DON'T CHANGE BELOW UNLESS YOU KNOW WHAT YOU ARE DOING
# If you wish to COMPLETELY overrride the pppd invocation:
# Example:
# OVERRIDE_PPPD_COMMAND="pppd call dsl"

# If you want adsl-connect to exit when connection drops:
# RETRY_ON_FAILURE=no
"""
155 156
    
    tmpl_options = """
157 158 159 160 161 162 163
noipdefault
hide-password
defaultroute
persist
lock
"""

164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
    def silentUnlink(self, path):
        """ Try to unlink a file, if exists """

        try:
            os.unlink(path)
        except:
            pass

    def capture(self, cmd):
        """ Run a command and capture the output """

        out = []
        a = popen2.Popen4(cmd)
        while 1:
            b = a.fromchild.readline()
            if b == None or b == "":
                break
            out.append(b)
        return (a.wait(), out)
183

184 185
    def getDNS(self):
        """ Try to get DNS server adress provided by remote peer """
186

187 188 189 190 191 192 193 194 195
        list = []
        try:
            f = file("/etc/ppp/resolv.conf", "r")
            for line in f.readlines():
                if line.strip().startswith("nameserver"):
                    list.append(line[line.find("nameserver") + 10:].rstrip('\n').strip())
            f.close()
        except IOError:
            return None
196

197
        return list
198

199 200
    def createConf(self, dev, user):
        """ Create configuration file for pppoe connections """
201

202 203 204 205 206 207 208
        self.silentUnlink("/etc/ppp/pppoe.conf")
        try:
            f = open("/etc/ppp/pppoe.conf", "w")
            f.write(self.tmpl_pppoe_conf % (dev, user))
            f.close()
        except:
            return True
209

210
        return None
211

212 213
    def createOptions(self):
        """ Create options file for pppoe connections """
214

215 216 217 218 219 220 221
        self.silentUnlink("/etc/ppp/options-pppoe")
        try:
            f = open("/etc/ppp/options-pppoe", "w")
            f.write(self.tmpl_options)
            f.close()
        except:
            return True
222

223
        return None
224

225 226
    def createSecrets(self, user, pwd):
        """ Create authentication files """
227

228 229 230 231 232 233 234 235 236 237 238 239 240 241
        try:
            # Ugly way to clean up secrets and recreate
            self.silentUnlink("/etc/ppp/pap-secrets")
            self.silentUnlink("/etc/ppp/chap-secrets")
            f = os.open("/etc/ppp/pap-secrets", os.O_CREAT, 0600)
            os.close(f)
            os.symlink("/etc/ppp/pap-secrets", "/etc/ppp/chap-secrets")
        except:
            return True
            
        f = open("/etc/ppp/pap-secrets", "w")
        data = "\"%s\" * \"%s\"\n" % (user, pwd)
        f.write(data)
        f.close()
242

243
        return None
244

245 246
    def getStatus(self):
        """ Stop the pppoe connection """
247

248 249
        cmd = "/usr/sbin/adsl-status"
        i, output = self.capture(cmd)
250

251
        return output
252

253 254
    def stopPPPD(self):
        """ Stop the pppoe connection """
255

256 257
        cmd = "/usr/sbin/adsl-stop"
        i, output = self.capture(cmd)
258

259
        return output
260

261 262
    def startPPPD(self):
        """ Start the PPP daemon """
263

264 265
        cmd = "/usr/sbin/adsl-start"
        i, output = self.capture(cmd)
266

267 268 269 270 271 272 273
        return output

    def connect(self, dev, user, pwd):
        """ Try to start a pppoe connection through dev and login """
    
        if self.createConf(dev, user) is True:
            return "Could not manage pppoe configuration"
274

275 276
        if self.createOptions() is True:
            return "Could not manage pppd parameters"
277

278 279
        if self.createSecrets(user, pwd) is True:
            return "Could not manage authentication files"
280

281 282
        output = self.startPPPD()
        return output
283 284

if __name__ == "__main__":
285 286
    rp = pppoe()
    rp.connect("eth0", "parbusman@uludag", "pek gizli")
287