serveur TFTP
alex
naoaqualis at aol.com
Thu Apr 24 10:22:26 EDT 2003
j'ai recupéré une librairie TFTP ecrit en python mais j'avoue avoir un
peu de mal à l'utiliser.comment faire un serveur TFTP avec? j'essai
d'identifier les methodes que je pourrais appliquer a un objet
mon_serveur par exemple :
import tftplib
mon_serveur = tftplib.TFTPServer()
...et aprés je suis un peu perdu.
voici la librairie tftplib.py:
#!/usr/bin/env python
#
#
# Standard imports
#
import string
import struct, socket, select
import thread
#
# Default variables
#
TFTP_PORT = 69
#
# TFTP Errors
#
class TFTPError(Exception):
pass
#
# A class for a TFTP Connection
#
class TFTPConnection:
RRQ = 1
WRQ = 2
DATA = 3
ACK = 4
ERR = 5
HDRSIZE = 4 # number of bytes for OPCODE and BLOCK in header
def __init__(self, host="", port=0,blocksize=512, timeout=2.0,
retry=5 ):
self.host = host
self.port = port
self.blocksize = blocksize
self.timeout = timeout
self.retry = retry
self.client_addr = None
self.sock = None
self.active = 0
self.blockNumber = 0
self.lastpkt = ""
self.mode = ""
self.filename = ""
self.file = None
self.bind(host, port)
# end __init__
def bind(self, host="", port=0):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock = sock
if host or port:
sock.bind(host, port)
# end start
def send(self, pkt=""):
self.sock.sendto(pkt, self.client_addr)
self.lastpkt = pkt
# end send
def recv(self):
sock = self.sock
F = sock.fileno()
client_addr = self.client_addr
timeout = self.timeout
retry = self.retry
while retry:
r,w,e = select.select( [F], [], [F], timeout)
if not r:
# We timed out -- retransmit
retry = retry - 1
self.retransmit()
else:
# Read data packet
pktsize = self.blocksize + self.HDRSIZE
data, addr = sock.recvfrom(pktsize)
if addr == client_addr:
break
else:
raise TFTPError(4, "Transfer timed out")
# end while
return self.parse(data)
# end recv
def parse(self, data, unpack=struct.unpack):
buf = buffer(data)
pkt = {}
opcode = pkt["opcode"] = unpack("!h", buf[:2])[0]
if ( opcode == self.RRQ ) or ( opcode == self.WRQ ):
filename, mode, junk = string.split(data[2:], "\000")
pkt["filename"] = filename
pkt["mode"] = mode
elif opcode == self.DATA:
block = pkt["block"] = unpack("!h", buf[2:4])[0]
data = pkt["data"] = buf[4:]
elif opcode == self.ACK:
block = pkt["block"] = unpack("!h", buf[2:4])[0]
elif opcode == self.ERR:
errnum = pkt["errnum"] = unpack("!h", buf[2:4])[0]
errtxt = pkt["errtxt"] = buf[4:-1]
else:
raise TFTPError(4, "Unknown packet type")
return pkt
# end recv
def retransmit(self):
self.sock.sendto(self.lastpkt, self.client_addr)
return
# end retransmit
def connect(self, addr, data):
self.client_addr = addr
RRQ = self.RRQ
WRQ = self.WRQ
DATA = self.DATA
ACK = self.ACK
ERR = self.ERR
try:
pkt = self.parse(data)
opcode = pkt["opcode"]
if opcode not in (RRQ, WRQ):
raise TFTPError(4, "Bad request")
# Start lock-step transfer
self.active = 1
if opcode == RRQ:
self.handleRRQ(pkt)
else:
self.handleWRQ(pkt)
# Loop until done
while self.active:
pkt = self.recv()
opcode = pkt["opcode"]
if opcode == DATA:
self.recvData(pkt)
elif opcode == ACK:
self.recvAck(pkt)
elif opcode == ERR:
self.recvErr(pkt)
else:
raise TFTPError(5, "Invalid opcode")
except TFTPError, detail:
self.sendError( detail[0], detail[1] )
return
# end connection
def recvAck(self, pkt):
if pkt["block"] == self.blockNumber:
# We received the correct ACK
self.handleACK(pkt)
return
# end recvAck
def recvData(self, pkt):
if pkt["block"] == self.blockNumber:
# We received the correct DATA packet
self.active = ( self.blocksize == len(pkt["data"]) )
self.handleDATA(pkt)
return
# end recvError
def recvErr(self, pkt):
self.handleERR(pkt)
self.retransmit()
# end recvErr
def sendData(self, data, pack=struct.pack):
blocksize = self.blocksize
block = self.blockNumber = self.blockNumber + 1
lendata = len(data)
format = "!hh%ds" % lendata
pkt = pack(format, self.DATA, block, data)
self.send(pkt)
self.active = (len(data) == blocksize)
# end sendData
def sendAck(self, pack=struct.pack):
block = self.blockNumber
self.blockNumber = self.blockNumber + 1
format = "!hh"
pkt = pack(format, self.ACK, block)
self.send(pkt)
# end sendAck
def sendError(self, errnum, errtext, pack=struct.pack):
errtext = errtext + "\000"
format = "!hh%ds" % len(errtext)
outdata = pack(format, self.ERR, errnum, errtext)
self.sock.sendto(outdata, self.client_addr)
return
# end sendError
#
#
# Override these handle* methods as needed
#
#
def handleRRQ(self, pkt):
filename = pkt["filename"]
mode = pkt["mode"]
self.file = self.readRequest(filename, mode)
self.sendData( self.file.read(self.blocksize) )
return
# end readFile
def handleWRQ(self, pkt):
filename = pkt["filename"]
mode = pkt["mode"]
self.file = self.writeRequest(filename, mode)
self.sendAck()
return
# end writeFile
def handleACK(self, pkt):
if self.active:
self.sendData( self.file.read(self.blocksize) )
return
# end handle ACK
def handleDATA(self, pkt):
self.sendAck()
data = pkt["data"]
self.file.write( data )
# end handleDATA
def handleERR(self, pkt):
print pkt["errtxt"]
return
# end handleERR
#
# You should definitely override these
#
def readRequest(self, filename, mode):
from StringIO import StringIO
return StringIO("")
# end readRequest
def writeRequest(self, filename, mode):
from StringIO import StringIO
return StringIO()
# end writeRequest
# end class TFTPConnection
#
# Simple TFTP Server
# Each connection is handled in its own thread.
#
class TFTPServer:
"""TFTP Server
Implements a threaded TFTP Server. Each request is handled
in its own thread
"""
def __init__(self, host="", port=TFTP_PORT,conn=TFTPConnection,
srcports=[] ):
self.host = host
self.port = port
self.conn = conn
self.srcports = srcports
self.sock = None
self.bind(host, port)
# end __init__
def bind(self, host, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock = sock
sock.bind(host, port)
# end start
def forever(self):
while 1:
data, addr = self.sock.recvfrom(516)
self.handle(addr, data)
# end serve_forever
def handle(self, addr, data):
if self.srcports:
nextport = self.srcports.pop(0)
self.srcports.append( nextport )
T = self.conn( self.host, nextport )
else:
T = self.conn( self.host )
thread.start_new_thread( T.connect, (addr, data) )
return
# end handle
# end class TFTPServer
if __name__ == "__main__":
import sys
from StringIO import StringIO
#
# Subclass to create our own TFTP Connection object
#
class MyTFTP( TFTPConnection ):
def readRequest(self, filename, mode):
randomstring = "Here is a sample string"
return StringIO( randomstring )
def writeRequest(self, filename, mode):
return StringIO()
# end class
port = 3000 + TFTP_PORT
if sys.argv[1:]:
port = string.atoi(sys.argv[1])
try:
serv = TFTPServer( "", port, conn=MyTFTP )
serv.forever()
except KeyboardInterrupt, SystemExit:
pass
d'avance merci.
Alex
More information about the Python-list
mailing list