mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	
		
			
	
	
		
			377 lines
		
	
	
	
		
			8.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			377 lines
		
	
	
	
		
			8.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 
								 | 
							
								# Implement (a subset of) Sun RPC, version 2 -- RFC1057.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import xdr
							 | 
						||
| 
								 | 
							
								import socket
							 | 
						||
| 
								 | 
							
								import os
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								RPCVERSION = 2
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								CALL = 0
							 | 
						||
| 
								 | 
							
								REPLY = 1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								AUTH_NULL = 0
							 | 
						||
| 
								 | 
							
								AUTH_UNIX = 1
							 | 
						||
| 
								 | 
							
								AUTH_SHORT = 2
							 | 
						||
| 
								 | 
							
								AUTH_DES = 3
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								MSG_ACCEPTED = 0
							 | 
						||
| 
								 | 
							
								MSG_DENIED = 1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SUCCESS = 0				# RPC executed successfully
							 | 
						||
| 
								 | 
							
								PROG_UNAVAIL  = 1			# remote hasn't exported program
							 | 
						||
| 
								 | 
							
								PROG_MISMATCH = 2			# remote can't support version #
							 | 
						||
| 
								 | 
							
								PROC_UNAVAIL  = 3			# program can't support procedure
							 | 
						||
| 
								 | 
							
								GARBAGE_ARGS  = 4			# procedure can't decode params
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								RPC_MISMATCH = 0			# RPC version number != 2
							 | 
						||
| 
								 | 
							
								AUTH_ERROR = 1				# remote can't authenticate caller
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								AUTH_BADCRED      = 1			# bad credentials (seal broken)
							 | 
						||
| 
								 | 
							
								AUTH_REJECTEDCRED = 2			# client must begin new session
							 | 
						||
| 
								 | 
							
								AUTH_BADVERF      = 3			# bad verifier (seal broken)
							 | 
						||
| 
								 | 
							
								AUTH_REJECTEDVERF = 4			# verifier expired or replayed
							 | 
						||
| 
								 | 
							
								AUTH_TOOWEAK      = 5			# rejected for security reasons
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class Packer(xdr.Packer):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def pack_auth(self, auth):
							 | 
						||
| 
								 | 
							
										flavor, stuff = auth
							 | 
						||
| 
								 | 
							
										self.pack_enum(flavor)
							 | 
						||
| 
								 | 
							
										self.pack_opaque(stuff)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def pack_auth_unix(self, stamp, machinename, uid, gid, gids):
							 | 
						||
| 
								 | 
							
										self.pack_uint(stamp)
							 | 
						||
| 
								 | 
							
										self.pack_string(machinename)
							 | 
						||
| 
								 | 
							
										self.pack_uint(uid)
							 | 
						||
| 
								 | 
							
										self.pack_uint(gid)
							 | 
						||
| 
								 | 
							
										self.pack_uint(len(gids))
							 | 
						||
| 
								 | 
							
										for i in gids:
							 | 
						||
| 
								 | 
							
											self.pack_uint(i)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def pack_callheader(self, xid, prog, vers, proc, cred, verf):
							 | 
						||
| 
								 | 
							
										self.pack_uint(xid)
							 | 
						||
| 
								 | 
							
										self.pack_enum(CALL)
							 | 
						||
| 
								 | 
							
										self.pack_uint(RPCVERSION)
							 | 
						||
| 
								 | 
							
										self.pack_uint(prog)
							 | 
						||
| 
								 | 
							
										self.pack_uint(vers)
							 | 
						||
| 
								 | 
							
										self.pack_uint(proc)
							 | 
						||
| 
								 | 
							
										self.pack_auth(cred)
							 | 
						||
| 
								 | 
							
										self.pack_auth(verf)
							 | 
						||
| 
								 | 
							
										# Caller must add procedure-specific part of call
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def pack_replyheader(self, xid, verf):
							 | 
						||
| 
								 | 
							
										self.pack_uint(xid)
							 | 
						||
| 
								 | 
							
										self.pack_enum(REPLY)
							 | 
						||
| 
								 | 
							
										self.pack_uint(MSG_ACCEPTED)
							 | 
						||
| 
								 | 
							
										self.pack_auth(verf)
							 | 
						||
| 
								 | 
							
										self.pack_enum(SUCCESS)
							 | 
						||
| 
								 | 
							
										# Caller must add procedure-specific part of reply
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class Unpacker(xdr.Unpacker):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def unpack_auth(self):
							 | 
						||
| 
								 | 
							
										flavor = self.unpack_enum()
							 | 
						||
| 
								 | 
							
										stuff = self.unpack_opaque()
							 | 
						||
| 
								 | 
							
										return (flavor, stuff)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def unpack_replyheader(self):
							 | 
						||
| 
								 | 
							
										xid = self.unpack_uint()
							 | 
						||
| 
								 | 
							
										mtype = self.unpack_enum()
							 | 
						||
| 
								 | 
							
										if mtype <> REPLY:
							 | 
						||
| 
								 | 
							
											raise RuntimeError, 'no REPLY but ' + str(mtype)
							 | 
						||
| 
								 | 
							
										stat = self.unpack_enum()
							 | 
						||
| 
								 | 
							
										if stat <> MSG_ACCEPTED:
							 | 
						||
| 
								 | 
							
											if stat == MSG_DENIED:
							 | 
						||
| 
								 | 
							
												stat = self.unpack_enum()
							 | 
						||
| 
								 | 
							
												if stat == RPC_MISMATCH:
							 | 
						||
| 
								 | 
							
													low = self.unpack_uint()
							 | 
						||
| 
								 | 
							
													high = self.unpack_uint()
							 | 
						||
| 
								 | 
							
													raise 'RPC_MISMATCH', (low, high)
							 | 
						||
| 
								 | 
							
												if stat == AUTH_ERROR:
							 | 
						||
| 
								 | 
							
													stat = self.unpack_uint()
							 | 
						||
| 
								 | 
							
													raise 'AUTH_ERROR', str(stat)
							 | 
						||
| 
								 | 
							
												raise 'MSG_REJECTED', str(stat)
							 | 
						||
| 
								 | 
							
											raise RuntimeError, 'no MSG_ACCEPTED but ' + str(stat)
							 | 
						||
| 
								 | 
							
										verf = self.unpack_auth()
							 | 
						||
| 
								 | 
							
										stat = self.unpack_enum()
							 | 
						||
| 
								 | 
							
										if stat <> SUCCESS:
							 | 
						||
| 
								 | 
							
											raise RuntimeError, 'no SUCCESS but ' + str(stat)
							 | 
						||
| 
								 | 
							
										return xid, verf
							 | 
						||
| 
								 | 
							
										# Caller must get procedure-specific part of reply
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Common base class for clients
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class Client:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def init(self, host, prog, vers, port, type):
							 | 
						||
| 
								 | 
							
										self.host = host
							 | 
						||
| 
								 | 
							
										self.prog = prog
							 | 
						||
| 
								 | 
							
										self.vers = vers
							 | 
						||
| 
								 | 
							
										self.port = port
							 | 
						||
| 
								 | 
							
										self.type = type
							 | 
						||
| 
								 | 
							
										self.sock = socket.socket(socket.AF_INET, type)
							 | 
						||
| 
								 | 
							
										self.sock.connect((host, port))
							 | 
						||
| 
								 | 
							
										self.lastxid = 0
							 | 
						||
| 
								 | 
							
										self.addpackers()
							 | 
						||
| 
								 | 
							
										self.cred = None
							 | 
						||
| 
								 | 
							
										self.verf = None
							 | 
						||
| 
								 | 
							
										return self
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def Null(self):			# Procedure 0 is always like this
							 | 
						||
| 
								 | 
							
										self.start_call(0)
							 | 
						||
| 
								 | 
							
										self.do_call(0)
							 | 
						||
| 
								 | 
							
										self.end_call()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def close(self):
							 | 
						||
| 
								 | 
							
										self.sock.close()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									# Functions that may be overridden by specific derived classes
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def addpackers(self):
							 | 
						||
| 
								 | 
							
										self.packer = Packer().init()
							 | 
						||
| 
								 | 
							
										self.unpacker = Unpacker().init('')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def mkcred(self, proc):
							 | 
						||
| 
								 | 
							
										if self.cred == None:
							 | 
						||
| 
								 | 
							
											p = Packer().init()
							 | 
						||
| 
								 | 
							
											p.pack_auth_unix(0, socket.gethostname(), \
							 | 
						||
| 
								 | 
							
												os.getuid(), os.getgid(), [])
							 | 
						||
| 
								 | 
							
											self.cred = p.get_buf()
							 | 
						||
| 
								 | 
							
										return (AUTH_UNIX, self.cred)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def mkverf(self, proc):
							 | 
						||
| 
								 | 
							
										return (AUTH_NULL, '')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Record-Marking standard support
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def sendfrag(sock, last, frag):
							 | 
						||
| 
								 | 
							
									x = len(frag)
							 | 
						||
| 
								 | 
							
									if last: x = x | 0x80000000L
							 | 
						||
| 
								 | 
							
									header = (chr(int(x>>24 & 0xff)) + chr(int(x>>16 & 0xff)) + \
							 | 
						||
| 
								 | 
							
										  chr(int(x>>8 & 0xff)) + chr(int(x & 0xff)))
							 | 
						||
| 
								 | 
							
									sock.send(header + frag)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def sendrecord(sock, record):
							 | 
						||
| 
								 | 
							
									sendfrag(sock, 1, record)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def recvfrag(sock):
							 | 
						||
| 
								 | 
							
									header = sock.recv(4)
							 | 
						||
| 
								 | 
							
									x = long(ord(header[0]))<<24 | ord(header[1])<<16 | \
							 | 
						||
| 
								 | 
							
									    ord(header[2])<<8 | ord(header[3])
							 | 
						||
| 
								 | 
							
									last = ((x & 0x80000000) != 0)
							 | 
						||
| 
								 | 
							
									n = int(x & 0x7fffffff)
							 | 
						||
| 
								 | 
							
									frag = ''
							 | 
						||
| 
								 | 
							
									while n > 0:
							 | 
						||
| 
								 | 
							
										buf = sock.recv(n)
							 | 
						||
| 
								 | 
							
										if not buf: raise EOFError
							 | 
						||
| 
								 | 
							
										n = n - len(buf)
							 | 
						||
| 
								 | 
							
										frag = frag + buf
							 | 
						||
| 
								 | 
							
									return last, frag
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def recvrecord(sock):
							 | 
						||
| 
								 | 
							
									record = ''
							 | 
						||
| 
								 | 
							
									last = 0
							 | 
						||
| 
								 | 
							
									while not last:
							 | 
						||
| 
								 | 
							
										last, frag = recvfrag(sock)
							 | 
						||
| 
								 | 
							
										record = record + frag
							 | 
						||
| 
								 | 
							
									return record
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Raw TCP-based client
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class RawTCPClient(Client):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def init(self, host, prog, vers, port):
							 | 
						||
| 
								 | 
							
										return Client.init(self, host, prog, vers, port, \
							 | 
						||
| 
								 | 
							
											socket.SOCK_STREAM)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def start_call(self, proc):
							 | 
						||
| 
								 | 
							
										self.lastxid = xid = self.lastxid + 1
							 | 
						||
| 
								 | 
							
										cred = self.mkcred(proc)
							 | 
						||
| 
								 | 
							
										verf = self.mkverf(proc)
							 | 
						||
| 
								 | 
							
										p = self.packer
							 | 
						||
| 
								 | 
							
										p.reset()
							 | 
						||
| 
								 | 
							
										p.pack_callheader(xid, self.prog, self.vers, proc, cred, verf)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def do_call(self, *rest):
							 | 
						||
| 
								 | 
							
										# rest is used for UDP buffer size; ignored for TCP
							 | 
						||
| 
								 | 
							
										call = self.packer.get_buf()
							 | 
						||
| 
								 | 
							
										sendrecord(self.sock, call)
							 | 
						||
| 
								 | 
							
										reply = recvrecord(self.sock)
							 | 
						||
| 
								 | 
							
										u = self.unpacker
							 | 
						||
| 
								 | 
							
										u.reset(reply)
							 | 
						||
| 
								 | 
							
										xid, verf = u.unpack_replyheader()
							 | 
						||
| 
								 | 
							
										if xid <> self.lastxid:
							 | 
						||
| 
								 | 
							
											# Can't really happen since this is TCP...
							 | 
						||
| 
								 | 
							
											raise RuntimeError, 'wrong xid in reply ' + `xid` + \
							 | 
						||
| 
								 | 
							
												' instead of ' + `self.lastxid`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def end_call(self):
							 | 
						||
| 
								 | 
							
										self.unpacker.done()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Raw UDP-based client
							 | 
						||
| 
								 | 
							
								# XXX This class does not recover from missed/duplicated packets!
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class RawUDPClient(Client):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def init(self, host, prog, vers, port):
							 | 
						||
| 
								 | 
							
										return Client.init(self, host, prog, vers, port, \
							 | 
						||
| 
								 | 
							
											socket.SOCK_DGRAM)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def start_call(self, proc):
							 | 
						||
| 
								 | 
							
										self.lastxid = xid = self.lastxid + 1
							 | 
						||
| 
								 | 
							
										cred = self.mkcred(proc)
							 | 
						||
| 
								 | 
							
										verf = self.mkverf(proc)
							 | 
						||
| 
								 | 
							
										p = self.packer
							 | 
						||
| 
								 | 
							
										p.reset()
							 | 
						||
| 
								 | 
							
										p.pack_callheader(xid, self.prog, self.vers, proc, cred, verf)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def do_call(self, *rest):
							 | 
						||
| 
								 | 
							
										if len(rest) == 0:
							 | 
						||
| 
								 | 
							
											bufsize = 8192
							 | 
						||
| 
								 | 
							
										elif len(rest) > 1:
							 | 
						||
| 
								 | 
							
											raise TypeError, 'too many args'
							 | 
						||
| 
								 | 
							
										else:
							 | 
						||
| 
								 | 
							
											bufsize = rest[0] + 512
							 | 
						||
| 
								 | 
							
										call = self.packer.get_buf()
							 | 
						||
| 
								 | 
							
										self.sock.send(call)
							 | 
						||
| 
								 | 
							
										# XXX What about time-out and retry?
							 | 
						||
| 
								 | 
							
										reply = self.sock.recv(bufsize)
							 | 
						||
| 
								 | 
							
										u = self.unpacker
							 | 
						||
| 
								 | 
							
										u.reset(reply)
							 | 
						||
| 
								 | 
							
										xid, verf = u.unpack_replyheader()
							 | 
						||
| 
								 | 
							
										if xid <> self.lastxid:
							 | 
						||
| 
								 | 
							
											# XXX Should assume it's an old reply
							 | 
						||
| 
								 | 
							
											raise RuntimeError, 'wrong xid in reply ' + `xid` + \
							 | 
						||
| 
								 | 
							
												' instead of ' + `self.lastxid`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def end_call(self):
							 | 
						||
| 
								 | 
							
										self.unpacker.done()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Port mapper interface
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								PMAP_PORT = 111
							 | 
						||
| 
								 | 
							
								PMAP_PROG = 100000
							 | 
						||
| 
								 | 
							
								PMAP_VERS = 2
							 | 
						||
| 
								 | 
							
								PMAPPROC_NULL = 0			# (void) -> void
							 | 
						||
| 
								 | 
							
								PMAPPROC_SET = 1			# (mapping) -> bool
							 | 
						||
| 
								 | 
							
								PMAPPROC_UNSET = 2			# (mapping) -> bool
							 | 
						||
| 
								 | 
							
								PMAPPROC_GETPORT = 3			# (mapping) -> unsigned int
							 | 
						||
| 
								 | 
							
								PMAPPROC_DUMP = 4			# (void) -> pmaplist
							 | 
						||
| 
								 | 
							
								PMAPPROC_CALLIT = 5			# (call_args) -> call_result
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# A mapping is (prog, vers, prot, port) and prot is one of:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								IPPROTO_TCP = 6
							 | 
						||
| 
								 | 
							
								IPPROTO_UDP = 17
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# A pmaplist is a variable-length list of mappings, as follows:
							 | 
						||
| 
								 | 
							
								# either (1, mapping, pmaplist) or (0).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# A call_args is (prog, vers, proc, args) where args is opaque;
							 | 
						||
| 
								 | 
							
								# a call_result is (port, res) where res is opaque.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class PortMapperPacker(Packer):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def pack_mapping(self, mapping):
							 | 
						||
| 
								 | 
							
										prog, vers, prot, port = mapping
							 | 
						||
| 
								 | 
							
										self.pack_uint(prog)
							 | 
						||
| 
								 | 
							
										self.pack_uint(vers)
							 | 
						||
| 
								 | 
							
										self.pack_uint(prot)
							 | 
						||
| 
								 | 
							
										self.pack_uint(port)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def pack_pmaplist(self, list):
							 | 
						||
| 
								 | 
							
										self.pack_list(list, self.pack_mapping)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class PortMapperUnpacker(Unpacker):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def unpack_mapping(self):
							 | 
						||
| 
								 | 
							
										prog = self.unpack_uint()
							 | 
						||
| 
								 | 
							
										vers = self.unpack_uint()
							 | 
						||
| 
								 | 
							
										prot = self.unpack_uint()
							 | 
						||
| 
								 | 
							
										port = self.unpack_uint()
							 | 
						||
| 
								 | 
							
										return prog, vers, prot, port
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def unpack_pmaplist(self):
							 | 
						||
| 
								 | 
							
										return self.unpack_list(self.unpack_mapping)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class PartialPortMapperClient:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def addpackers(self):
							 | 
						||
| 
								 | 
							
										self.packer = PortMapperPacker().init()
							 | 
						||
| 
								 | 
							
										self.unpacker = PortMapperUnpacker().init('')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def Getport(self, mapping):
							 | 
						||
| 
								 | 
							
										self.start_call(PMAPPROC_GETPORT)
							 | 
						||
| 
								 | 
							
										self.packer.pack_mapping(mapping)
							 | 
						||
| 
								 | 
							
										self.do_call(4)
							 | 
						||
| 
								 | 
							
										port = self.unpacker.unpack_uint()
							 | 
						||
| 
								 | 
							
										self.end_call()
							 | 
						||
| 
								 | 
							
										return port
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def Dump(self):
							 | 
						||
| 
								 | 
							
										self.start_call(PMAPPROC_DUMP)
							 | 
						||
| 
								 | 
							
										self.do_call(8192-512)
							 | 
						||
| 
								 | 
							
										list = self.unpacker.unpack_pmaplist()
							 | 
						||
| 
								 | 
							
										self.end_call()
							 | 
						||
| 
								 | 
							
										return list
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class TCPPortMapperClient(PartialPortMapperClient, RawTCPClient):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def init(self, host):
							 | 
						||
| 
								 | 
							
										return RawTCPClient.init(self, \
							 | 
						||
| 
								 | 
							
											host, PMAP_PROG, PMAP_VERS, PMAP_PORT)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class UDPPortMapperClient(PartialPortMapperClient, RawUDPClient):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def init(self, host):
							 | 
						||
| 
								 | 
							
										return RawUDPClient.init(self, \
							 | 
						||
| 
								 | 
							
											host, PMAP_PROG, PMAP_VERS, PMAP_PORT)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class TCPClient(RawTCPClient):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def init(self, host, prog, vers):
							 | 
						||
| 
								 | 
							
										pmap = TCPPortMapperClient().init(host)
							 | 
						||
| 
								 | 
							
										port = pmap.Getport((prog, vers, IPPROTO_TCP, 0))
							 | 
						||
| 
								 | 
							
										pmap.close()
							 | 
						||
| 
								 | 
							
										return RawTCPClient.init(self, host, prog, vers, port)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class UDPClient(RawUDPClient):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									def init(self, host, prog, vers):
							 | 
						||
| 
								 | 
							
										pmap = UDPPortMapperClient().init(host)
							 | 
						||
| 
								 | 
							
										port = pmap.Getport((prog, vers, IPPROTO_UDP, 0))
							 | 
						||
| 
								 | 
							
										pmap.close()
							 | 
						||
| 
								 | 
							
										return RawUDPClient.init(self, host, prog, vers, port)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def test():
							 | 
						||
| 
								 | 
							
									import T
							 | 
						||
| 
								 | 
							
									T.TSTART()
							 | 
						||
| 
								 | 
							
									pmap = UDPPortMapperClient().init('')
							 | 
						||
| 
								 | 
							
									T.TSTOP()
							 | 
						||
| 
								 | 
							
									pmap.Null()
							 | 
						||
| 
								 | 
							
									T.TSTOP()
							 | 
						||
| 
								 | 
							
									list = pmap.Dump()
							 | 
						||
| 
								 | 
							
									T.TSTOP()
							 | 
						||
| 
								 | 
							
									list.sort()
							 | 
						||
| 
								 | 
							
									for prog, vers, prot, port in list:
							 | 
						||
| 
								 | 
							
										print prog, vers,
							 | 
						||
| 
								 | 
							
										if prot == IPPROTO_TCP: print 'tcp',
							 | 
						||
| 
								 | 
							
										elif prot == IPPROTO_UDP: print 'udp',
							 | 
						||
| 
								 | 
							
										else: print prot,
							 | 
						||
| 
								 | 
							
										print port
							 |