1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-30 08:19:09 +00:00

Bring in a hybrid of SunSoft's transport-independent RPC (TI-RPC) and

associated changes that had to happen to make this possible as well as
bugs fixed along the way.

  Bring in required TLI library routines to support this.

  Since we don't support TLI we've essentially copied what NetBSD
  has done, adding a thin layer to emulate direct the TLI calls
  into BSD socket calls.

  This is mostly from Sun's tirpc release that was made in 1994,
  however some fixes were backported from the 1999 release (supposedly
  only made available after this porting effort was underway).

  The submitter has agreed to continue on and bring us up to the
  1999 release.

  Several key features are introduced with this update:
    Client calls are thread safe. (1999 code has server side thread
    safe)
    Updated, a more modern interface.

  Many userland updates were done to bring the code up to par with
  the recent RPC API.

  There is an update to the pthreads library, a function
  pthread_main_np() was added to emulate a function of Sun's threads
  library.

  While we're at it, bring in NetBSD's lockd, it's been far too
  long of a wait.

  New rpcbind(8) replaces portmap(8) (supporting communication over
  an authenticated Unix-domain socket, and by default only allowing
  set and unset requests over that channel). It's much more secure
  than the old portmapper.

  Umount(8), mountd(8), mount_nfs(8), nfsd(8) have also been upgraded
  to support TI-RPC and to support IPV6.

  Umount(8) is also fixed to unmount pathnames longer than 80 chars,
  which are currently truncated by the Kernel statfs structure.

Submitted by: Martin Blapp <mb@imp.ch>
Manpage review: ru
Secure RPC implemented by: wpaul
This commit is contained in:
Alfred Perlstein 2001-03-19 12:50:13 +00:00
parent 1ac2b9fe97
commit 8360efbd6c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=74462
204 changed files with 32059 additions and 12117 deletions

View File

@ -10,7 +10,7 @@ BIN1= amd.map apmd.conf auth.conf \
dhclient.conf dm.conf fbtab ftpusers gettytab group \
hosts hosts.allow hosts.equiv hosts.lpd \
inetd.conf login.access login.conf \
motd modems networks newsyslog.conf \
motd modems netconfig networks newsyslog.conf \
pam.conf phones pim6dd.conf pim6sd.conf \
printcap profile protocols \
rc rc.atm rc.devfs rc.diskless1 rc.diskless2 rc.firewall rc.firewall6 \

View File

@ -101,7 +101,7 @@ ppp_nat="YES" # Use PPP's internal network address translation or NO.
ppp_profile="papchap" # Which profile to use from /etc/ppp/ppp.conf.
ppp_user="root" # Which user to run ppp as
### Network daemon (miscellaneous) & NFS options: ###
### Network daemon (miscellaneous) ###
syslogd_enable="YES" # Run syslog daemon (or NO).
syslogd_flags="-s" # Flags to syslogd (if enabled).
inetd_enable="NO" # Run the network daemon dispatcher (YES/NO).
@ -121,6 +121,19 @@ kadmind_server_enable="NO" # Run kadmind (or NO) -- do not run on
kerberos_stash="" # Is the kerberos master key stashed?
rwhod_enable="NO" # Run the rwho daemon (or NO).
rwhod_flags="" # Flags for rwhod
rarpd_enable="NO" # Run rarpd (or NO).
rarpd_flags="" # Flags to rarpd.
xtend_enable="NO" # Run the X-10 power controller daemon.
xtend_flags="" # Flags to xtend (if enabled).
pppoed_enable="NO" # Run the PPP over Ethernet daemon.
pppoed_provider="*" # Provider and ppp(8) config file entry.
pppoed_flags="-P /var/run/pppoed.pid" # Flags to pppoed (if enabled).
pppoed_interface="fxp0" # The interface that pppoed runs on.
sshd_enable="NO" # Enable sshd
sshd_program="/usr/sbin/sshd" # path to sshd, if you want a different one.
sshd_flags="" # Additional flags for sshd.
### Network daemon (NFS) Need all portmap_enable="YES" ###
amd_enable="NO" # Run amd service with $amd_flags (or NO).
amd_flags="-a /.amd_mnt -l syslog /host /etc/amd.map /net /etc/amd.map"
amd_map_program="NO" # Can be set to "ypcat -k amd.master"
@ -135,24 +148,13 @@ weak_mountd_authentication="NO" # Allow non-root mount requests to be served.
nfs_reserved_port_only="NO" # Provide NFS only on secure port (or NO).
nfs_bufpackets="DEFAULT" # bufspace (in packets) for client (or DEFAULT)
rpc_lockd_enable="NO" # Run NFS rpc.lockd (*broken!*) if nfs_server.
rpc_statd_enable="YES" # Run NFS rpc.statd if nfs_server (or NO).
rpc_statd_enable="NO" # Run NFS rpc.statd if nfs_server (or NO).
portmap_enable="NO" # Run the portmapper service (YES/NO).
portmap_program="/usr/sbin/portmap" # path to portmap, if you want a different one.
portmap_program="/usr/sbin/rpcbind" # path to portmap, if you want a different one.
portmap_flags="" # Flags to portmap (if enabled).
rpc_ypupdated_enable="NO" # Run if NIS master and SecureRPC (or NO).
keyserv_enable="NO" # Run the SecureRPC keyserver (or NO).
keyserv_flags="" # Flags to keyserv (if enabled).
rarpd_enable="NO" # Run rarpd (or NO).
rarpd_flags="" # Flags to rarpd.
xtend_enable="NO" # Run the X-10 power controller daemon.
xtend_flags="" # Flags to xtend (if enabled).
pppoed_enable="NO" # Run the PPP over Ethernet daemon.
pppoed_provider="*" # Provider and ppp(8) config file entry.
pppoed_flags="-P /var/run/pppoed.pid" # Flags to pppoed (if enabled).
pppoed_interface="fxp0" # The interface that pppoed runs on.
sshd_enable="NO" # Enable sshd
sshd_program="/usr/sbin/sshd" # path to sshd, if you want a different one.
sshd_flags="" # Additional flags for sshd.
### Network Time Services options: ###
timed_enable="NO" # Run the time daemon (or NO).
@ -164,7 +166,7 @@ xntpd_enable="NO" # Run ntpd Network Time Protocol (or NO).
xntpd_program="ntpd" # path to ntpd, if you want a different one.
xntpd_flags="-p /var/run/ntpd.pid" # Flags to ntpd (if enabled).
# Network Information Services (NIS) options: ###
# Network Information Services (NIS) options: Need all portmap_enable="YES" ###
nis_client_enable="NO" # We're an NIS client (or NO).
nis_client_flags="" # Flags to ypbind (if enabled).
nis_ypset_enable="NO" # Run ypset at boot time (or NO).

17
etc/netconfig Normal file
View File

@ -0,0 +1,17 @@
# The network configuration file. This file is currently only used in
# conjunction with the (TI-) RPC code in the C library, unlike its
# use in SVR4.
#
# Entries consist of:
#
# <network_id> <semantics> <flags> <protofamily> <protoname> \
# <device> <nametoaddr_libs>
#
# The <device> and <nametoaddr_libs> fields are always empty in FreeBSD.
#
udp6 tpi_clts v inet6 udp - -
tcp6 tpi_cots_ord v inet6 tcp - -
udp tpi_clts v inet udp - -
tcp tpi_cots_ord v inet tcp - -
rawip tpi_raw - inet - - -
unix tpi_cots_ord - loopback - - -

View File

@ -514,59 +514,61 @@ network_pass2() {
case ${portmap_enable} in
[Yy][Ee][Ss])
echo -n ' portmap'; ${portmap_program:-/usr/sbin/portmap} ${portmap_flags}
;;
esac
echo -n ' rpcbind'; ${portmap_program:-/usr/sbin/rpcbind} \
${portmap_flags}
# Start ypserv if we're an NIS server.
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
#
case ${nis_server_enable} in
[Yy][Ee][Ss])
echo -n ' ypserv'; ypserv ${nis_server_flags}
case ${nis_ypxfrd_enable} in
# Start ypserv if we're an NIS server.
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
#
case ${nis_server_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypxfrd'
rpc.ypxfrd ${nis_ypxfrd_flags}
echo -n ' ypserv'; ypserv ${nis_server_flags}
case ${nis_ypxfrd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypxfrd'
rpc.ypxfrd ${nis_ypxfrd_flags}
;;
esac
case ${nis_yppasswdd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.yppasswdd'
rpc.yppasswdd ${nis_yppasswdd_flags}
;;
esac
;;
esac
case ${nis_yppasswdd_enable} in
# Start ypbind if we're an NIS client
#
case ${nis_client_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.yppasswdd'
rpc.yppasswdd ${nis_yppasswdd_flags}
echo -n ' ypbind'; ypbind ${nis_client_flags}
case ${nis_ypset_enable} in
[Yy][Ee][Ss])
echo -n ' ypset'; ypset ${nis_ypset_flags}
;;
esac
;;
esac
;;
esac
# Start ypbind if we're an NIS client
#
case ${nis_client_enable} in
[Yy][Ee][Ss])
echo -n ' ypbind'; ypbind ${nis_client_flags}
case ${nis_ypset_enable} in
# Start keyserv if we are running Secure RPC
#
case ${keyserv_enable} in
[Yy][Ee][Ss])
echo -n ' ypset'; ypset ${nis_ypset_flags}
echo -n ' keyserv'; keyserv ${keyserv_flags}
;;
esac
;;
esac
# Start keyserv if we are running Secure RPC
#
case ${keyserv_enable} in
[Yy][Ee][Ss])
echo -n ' keyserv'; keyserv ${keyserv_flags}
;;
esac
# Start ypupdated if we are running Secure RPC and we are NIS master
#
case ${rpc_ypupdated_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypupdated'; rpc.ypupdated
# Start ypupdated if we are running Secure RPC
# and we are NIS master
#
case ${rpc_ypupdated_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypupdated'; rpc.ypupdated
;;
esac
;;
esac
@ -582,99 +584,103 @@ network_pass2() {
network_pass3() {
echo -n 'Starting final network daemons:'
case ${nfs_server_enable} in
case ${portmap_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="${mountd_flags} -n"
;;
esac
mountd ${mountd_flags}
case ${nfs_reserved_port_only} in
[Yy][Ee][Ss])
echo -n ' NFS on reserved port only=YES'
sysctl -w vfs.nfs.nfs_privport=1 >/dev/null
;;
esac
echo -n ' nfsd'; nfsd ${nfs_server_flags}
if [ -n "${nfs_bufpackets}" ]; then
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} \
> /dev/null
fi
case ${rpc_lockd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.lockd'; rpc.lockd
;;
esac
case ${rpc_statd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.statd'; rpc.statd
;;
esac
fi
;;
*)
case ${single_mountd_enable} in
case ${nfs_server_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="-n"
mountd_flags="${mountd_flags} -n"
;;
esac
mountd ${mountd_flags}
case ${nfs_reserved_port_only} in
[Yy][Ee][Ss])
echo -n ' NFS on reserved port only=YES'
sysctl -w vfs.nfs.nfs_privport=1 > /dev/null
;;
esac
echo -n ' nfsd'; nfsd ${nfs_server_flags}
if [ -n "${nfs_bufpackets}" ]; then
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} > /dev/null
fi
case ${rpc_lockd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.lockd'; rpc.lockd
;;
esac
case ${rpc_statd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.statd'; rpc.statd
;;
esac
fi
;;
*)
case ${single_mountd_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="-n"
;;
esac
mountd ${mountd_flags}
fi
;;
esac
;;
esac
case ${nfs_client_enable} in
[Yy][Ee][Ss])
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
if [ -n "${nfs_access_cache}" ]; then
echo -n " NFS access cache time=${nfs_access_cache}"
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} >/dev/null
fi
;;
esac
;;
esac
case ${nfs_client_enable} in
[Yy][Ee][Ss])
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
if [ -n "${nfs_access_cache}" ]; then
echo -n " NFS access cache time=${nfs_access_cache}"
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} \
>/dev/null
# If /var/db/mounttab exists, some nfs-server has not been
# sucessfully notified about a previous client shutdown.
# If there is no /var/db/mounttab, we do nothing.
if [ -f /var/db/mounttab ]; then
rpc.umntall -k
fi
;;
esac
# If /var/db/mounttab exists, some nfs-server has not been
# sucessfully notified about a previous client shutdown.
# If there is no /var/db/mounttab, we do nothing.
if [ -f /var/db/mounttab ]; then
rpc.umntall -k
fi
case ${amd_enable} in
[Yy][Ee][Ss])
echo -n ' amd'
case ${amd_map_program} in
[Nn][Oo] | '')
;;
*)
amd_flags="${amd_flags} `eval ${amd_map_program}`"
;;
case ${amd_enable} in
[Yy][Ee][Ss])
echo -n ' amd'
case ${amd_map_program} in
[Nn][Oo] | '')
;;
*)
amd_flags="${amd_flags} `eval\
${amd_map_program}`"
;;
esac
if [ -n "${amd_flags}" ]; then
amd -p ${amd_flags} > /var/run/amd.pid 2> /dev/null
else
amd 2> /dev/null
fi
if [ -n "${amd_flags}" ]; then
amd -p ${amd_flags}\
> /var/run/amd.pid 2> /dev/null
else
amd 2> /dev/null
fi
;;
esac
;;
esac

View File

@ -514,59 +514,61 @@ network_pass2() {
case ${portmap_enable} in
[Yy][Ee][Ss])
echo -n ' portmap'; ${portmap_program:-/usr/sbin/portmap} ${portmap_flags}
;;
esac
echo -n ' rpcbind'; ${portmap_program:-/usr/sbin/rpcbind} \
${portmap_flags}
# Start ypserv if we're an NIS server.
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
#
case ${nis_server_enable} in
[Yy][Ee][Ss])
echo -n ' ypserv'; ypserv ${nis_server_flags}
case ${nis_ypxfrd_enable} in
# Start ypserv if we're an NIS server.
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
#
case ${nis_server_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypxfrd'
rpc.ypxfrd ${nis_ypxfrd_flags}
echo -n ' ypserv'; ypserv ${nis_server_flags}
case ${nis_ypxfrd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypxfrd'
rpc.ypxfrd ${nis_ypxfrd_flags}
;;
esac
case ${nis_yppasswdd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.yppasswdd'
rpc.yppasswdd ${nis_yppasswdd_flags}
;;
esac
;;
esac
case ${nis_yppasswdd_enable} in
# Start ypbind if we're an NIS client
#
case ${nis_client_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.yppasswdd'
rpc.yppasswdd ${nis_yppasswdd_flags}
echo -n ' ypbind'; ypbind ${nis_client_flags}
case ${nis_ypset_enable} in
[Yy][Ee][Ss])
echo -n ' ypset'; ypset ${nis_ypset_flags}
;;
esac
;;
esac
;;
esac
# Start ypbind if we're an NIS client
#
case ${nis_client_enable} in
[Yy][Ee][Ss])
echo -n ' ypbind'; ypbind ${nis_client_flags}
case ${nis_ypset_enable} in
# Start keyserv if we are running Secure RPC
#
case ${keyserv_enable} in
[Yy][Ee][Ss])
echo -n ' ypset'; ypset ${nis_ypset_flags}
echo -n ' keyserv'; keyserv ${keyserv_flags}
;;
esac
;;
esac
# Start keyserv if we are running Secure RPC
#
case ${keyserv_enable} in
[Yy][Ee][Ss])
echo -n ' keyserv'; keyserv ${keyserv_flags}
;;
esac
# Start ypupdated if we are running Secure RPC and we are NIS master
#
case ${rpc_ypupdated_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypupdated'; rpc.ypupdated
# Start ypupdated if we are running Secure RPC
# and we are NIS master
#
case ${rpc_ypupdated_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypupdated'; rpc.ypupdated
;;
esac
;;
esac
@ -582,99 +584,103 @@ network_pass2() {
network_pass3() {
echo -n 'Starting final network daemons:'
case ${nfs_server_enable} in
case ${portmap_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="${mountd_flags} -n"
;;
esac
mountd ${mountd_flags}
case ${nfs_reserved_port_only} in
[Yy][Ee][Ss])
echo -n ' NFS on reserved port only=YES'
sysctl -w vfs.nfs.nfs_privport=1 >/dev/null
;;
esac
echo -n ' nfsd'; nfsd ${nfs_server_flags}
if [ -n "${nfs_bufpackets}" ]; then
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} \
> /dev/null
fi
case ${rpc_lockd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.lockd'; rpc.lockd
;;
esac
case ${rpc_statd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.statd'; rpc.statd
;;
esac
fi
;;
*)
case ${single_mountd_enable} in
case ${nfs_server_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="-n"
mountd_flags="${mountd_flags} -n"
;;
esac
mountd ${mountd_flags}
case ${nfs_reserved_port_only} in
[Yy][Ee][Ss])
echo -n ' NFS on reserved port only=YES'
sysctl -w vfs.nfs.nfs_privport=1 > /dev/null
;;
esac
echo -n ' nfsd'; nfsd ${nfs_server_flags}
if [ -n "${nfs_bufpackets}" ]; then
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} > /dev/null
fi
case ${rpc_lockd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.lockd'; rpc.lockd
;;
esac
case ${rpc_statd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.statd'; rpc.statd
;;
esac
fi
;;
*)
case ${single_mountd_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="-n"
;;
esac
mountd ${mountd_flags}
fi
;;
esac
;;
esac
case ${nfs_client_enable} in
[Yy][Ee][Ss])
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
if [ -n "${nfs_access_cache}" ]; then
echo -n " NFS access cache time=${nfs_access_cache}"
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} >/dev/null
fi
;;
esac
;;
esac
case ${nfs_client_enable} in
[Yy][Ee][Ss])
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
if [ -n "${nfs_access_cache}" ]; then
echo -n " NFS access cache time=${nfs_access_cache}"
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} \
>/dev/null
# If /var/db/mounttab exists, some nfs-server has not been
# sucessfully notified about a previous client shutdown.
# If there is no /var/db/mounttab, we do nothing.
if [ -f /var/db/mounttab ]; then
rpc.umntall -k
fi
;;
esac
# If /var/db/mounttab exists, some nfs-server has not been
# sucessfully notified about a previous client shutdown.
# If there is no /var/db/mounttab, we do nothing.
if [ -f /var/db/mounttab ]; then
rpc.umntall -k
fi
case ${amd_enable} in
[Yy][Ee][Ss])
echo -n ' amd'
case ${amd_map_program} in
[Nn][Oo] | '')
;;
*)
amd_flags="${amd_flags} `eval ${amd_map_program}`"
;;
case ${amd_enable} in
[Yy][Ee][Ss])
echo -n ' amd'
case ${amd_map_program} in
[Nn][Oo] | '')
;;
*)
amd_flags="${amd_flags} `eval\
${amd_map_program}`"
;;
esac
if [ -n "${amd_flags}" ]; then
amd -p ${amd_flags} > /var/run/amd.pid 2> /dev/null
else
amd 2> /dev/null
fi
if [ -n "${amd_flags}" ]; then
amd -p ${amd_flags}\
> /var/run/amd.pid 2> /dev/null
else
amd 2> /dev/null
fi
;;
esac
;;
esac

View File

@ -514,59 +514,61 @@ network_pass2() {
case ${portmap_enable} in
[Yy][Ee][Ss])
echo -n ' portmap'; ${portmap_program:-/usr/sbin/portmap} ${portmap_flags}
;;
esac
echo -n ' rpcbind'; ${portmap_program:-/usr/sbin/rpcbind} \
${portmap_flags}
# Start ypserv if we're an NIS server.
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
#
case ${nis_server_enable} in
[Yy][Ee][Ss])
echo -n ' ypserv'; ypserv ${nis_server_flags}
case ${nis_ypxfrd_enable} in
# Start ypserv if we're an NIS server.
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
#
case ${nis_server_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypxfrd'
rpc.ypxfrd ${nis_ypxfrd_flags}
echo -n ' ypserv'; ypserv ${nis_server_flags}
case ${nis_ypxfrd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypxfrd'
rpc.ypxfrd ${nis_ypxfrd_flags}
;;
esac
case ${nis_yppasswdd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.yppasswdd'
rpc.yppasswdd ${nis_yppasswdd_flags}
;;
esac
;;
esac
case ${nis_yppasswdd_enable} in
# Start ypbind if we're an NIS client
#
case ${nis_client_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.yppasswdd'
rpc.yppasswdd ${nis_yppasswdd_flags}
echo -n ' ypbind'; ypbind ${nis_client_flags}
case ${nis_ypset_enable} in
[Yy][Ee][Ss])
echo -n ' ypset'; ypset ${nis_ypset_flags}
;;
esac
;;
esac
;;
esac
# Start ypbind if we're an NIS client
#
case ${nis_client_enable} in
[Yy][Ee][Ss])
echo -n ' ypbind'; ypbind ${nis_client_flags}
case ${nis_ypset_enable} in
# Start keyserv if we are running Secure RPC
#
case ${keyserv_enable} in
[Yy][Ee][Ss])
echo -n ' ypset'; ypset ${nis_ypset_flags}
echo -n ' keyserv'; keyserv ${keyserv_flags}
;;
esac
;;
esac
# Start keyserv if we are running Secure RPC
#
case ${keyserv_enable} in
[Yy][Ee][Ss])
echo -n ' keyserv'; keyserv ${keyserv_flags}
;;
esac
# Start ypupdated if we are running Secure RPC and we are NIS master
#
case ${rpc_ypupdated_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypupdated'; rpc.ypupdated
# Start ypupdated if we are running Secure RPC
# and we are NIS master
#
case ${rpc_ypupdated_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypupdated'; rpc.ypupdated
;;
esac
;;
esac
@ -582,99 +584,103 @@ network_pass2() {
network_pass3() {
echo -n 'Starting final network daemons:'
case ${nfs_server_enable} in
case ${portmap_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="${mountd_flags} -n"
;;
esac
mountd ${mountd_flags}
case ${nfs_reserved_port_only} in
[Yy][Ee][Ss])
echo -n ' NFS on reserved port only=YES'
sysctl -w vfs.nfs.nfs_privport=1 >/dev/null
;;
esac
echo -n ' nfsd'; nfsd ${nfs_server_flags}
if [ -n "${nfs_bufpackets}" ]; then
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} \
> /dev/null
fi
case ${rpc_lockd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.lockd'; rpc.lockd
;;
esac
case ${rpc_statd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.statd'; rpc.statd
;;
esac
fi
;;
*)
case ${single_mountd_enable} in
case ${nfs_server_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="-n"
mountd_flags="${mountd_flags} -n"
;;
esac
mountd ${mountd_flags}
case ${nfs_reserved_port_only} in
[Yy][Ee][Ss])
echo -n ' NFS on reserved port only=YES'
sysctl -w vfs.nfs.nfs_privport=1 > /dev/null
;;
esac
echo -n ' nfsd'; nfsd ${nfs_server_flags}
if [ -n "${nfs_bufpackets}" ]; then
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} > /dev/null
fi
case ${rpc_lockd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.lockd'; rpc.lockd
;;
esac
case ${rpc_statd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.statd'; rpc.statd
;;
esac
fi
;;
*)
case ${single_mountd_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="-n"
;;
esac
mountd ${mountd_flags}
fi
;;
esac
;;
esac
case ${nfs_client_enable} in
[Yy][Ee][Ss])
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
if [ -n "${nfs_access_cache}" ]; then
echo -n " NFS access cache time=${nfs_access_cache}"
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} >/dev/null
fi
;;
esac
;;
esac
case ${nfs_client_enable} in
[Yy][Ee][Ss])
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
if [ -n "${nfs_access_cache}" ]; then
echo -n " NFS access cache time=${nfs_access_cache}"
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} \
>/dev/null
# If /var/db/mounttab exists, some nfs-server has not been
# sucessfully notified about a previous client shutdown.
# If there is no /var/db/mounttab, we do nothing.
if [ -f /var/db/mounttab ]; then
rpc.umntall -k
fi
;;
esac
# If /var/db/mounttab exists, some nfs-server has not been
# sucessfully notified about a previous client shutdown.
# If there is no /var/db/mounttab, we do nothing.
if [ -f /var/db/mounttab ]; then
rpc.umntall -k
fi
case ${amd_enable} in
[Yy][Ee][Ss])
echo -n ' amd'
case ${amd_map_program} in
[Nn][Oo] | '')
;;
*)
amd_flags="${amd_flags} `eval ${amd_map_program}`"
;;
case ${amd_enable} in
[Yy][Ee][Ss])
echo -n ' amd'
case ${amd_map_program} in
[Nn][Oo] | '')
;;
*)
amd_flags="${amd_flags} `eval\
${amd_map_program}`"
;;
esac
if [ -n "${amd_flags}" ]; then
amd -p ${amd_flags} > /var/run/amd.pid 2> /dev/null
else
amd 2> /dev/null
fi
if [ -n "${amd_flags}" ]; then
amd -p ${amd_flags}\
> /var/run/amd.pid 2> /dev/null
else
amd 2> /dev/null
fi
;;
esac
;;
esac

View File

@ -514,59 +514,61 @@ network_pass2() {
case ${portmap_enable} in
[Yy][Ee][Ss])
echo -n ' portmap'; ${portmap_program:-/usr/sbin/portmap} ${portmap_flags}
;;
esac
echo -n ' rpcbind'; ${portmap_program:-/usr/sbin/rpcbind} \
${portmap_flags}
# Start ypserv if we're an NIS server.
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
#
case ${nis_server_enable} in
[Yy][Ee][Ss])
echo -n ' ypserv'; ypserv ${nis_server_flags}
case ${nis_ypxfrd_enable} in
# Start ypserv if we're an NIS server.
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
#
case ${nis_server_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypxfrd'
rpc.ypxfrd ${nis_ypxfrd_flags}
echo -n ' ypserv'; ypserv ${nis_server_flags}
case ${nis_ypxfrd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypxfrd'
rpc.ypxfrd ${nis_ypxfrd_flags}
;;
esac
case ${nis_yppasswdd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.yppasswdd'
rpc.yppasswdd ${nis_yppasswdd_flags}
;;
esac
;;
esac
case ${nis_yppasswdd_enable} in
# Start ypbind if we're an NIS client
#
case ${nis_client_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.yppasswdd'
rpc.yppasswdd ${nis_yppasswdd_flags}
echo -n ' ypbind'; ypbind ${nis_client_flags}
case ${nis_ypset_enable} in
[Yy][Ee][Ss])
echo -n ' ypset'; ypset ${nis_ypset_flags}
;;
esac
;;
esac
;;
esac
# Start ypbind if we're an NIS client
#
case ${nis_client_enable} in
[Yy][Ee][Ss])
echo -n ' ypbind'; ypbind ${nis_client_flags}
case ${nis_ypset_enable} in
# Start keyserv if we are running Secure RPC
#
case ${keyserv_enable} in
[Yy][Ee][Ss])
echo -n ' ypset'; ypset ${nis_ypset_flags}
echo -n ' keyserv'; keyserv ${keyserv_flags}
;;
esac
;;
esac
# Start keyserv if we are running Secure RPC
#
case ${keyserv_enable} in
[Yy][Ee][Ss])
echo -n ' keyserv'; keyserv ${keyserv_flags}
;;
esac
# Start ypupdated if we are running Secure RPC and we are NIS master
#
case ${rpc_ypupdated_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypupdated'; rpc.ypupdated
# Start ypupdated if we are running Secure RPC
# and we are NIS master
#
case ${rpc_ypupdated_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypupdated'; rpc.ypupdated
;;
esac
;;
esac
@ -582,99 +584,103 @@ network_pass2() {
network_pass3() {
echo -n 'Starting final network daemons:'
case ${nfs_server_enable} in
case ${portmap_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="${mountd_flags} -n"
;;
esac
mountd ${mountd_flags}
case ${nfs_reserved_port_only} in
[Yy][Ee][Ss])
echo -n ' NFS on reserved port only=YES'
sysctl -w vfs.nfs.nfs_privport=1 >/dev/null
;;
esac
echo -n ' nfsd'; nfsd ${nfs_server_flags}
if [ -n "${nfs_bufpackets}" ]; then
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} \
> /dev/null
fi
case ${rpc_lockd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.lockd'; rpc.lockd
;;
esac
case ${rpc_statd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.statd'; rpc.statd
;;
esac
fi
;;
*)
case ${single_mountd_enable} in
case ${nfs_server_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="-n"
mountd_flags="${mountd_flags} -n"
;;
esac
mountd ${mountd_flags}
case ${nfs_reserved_port_only} in
[Yy][Ee][Ss])
echo -n ' NFS on reserved port only=YES'
sysctl -w vfs.nfs.nfs_privport=1 > /dev/null
;;
esac
echo -n ' nfsd'; nfsd ${nfs_server_flags}
if [ -n "${nfs_bufpackets}" ]; then
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} > /dev/null
fi
case ${rpc_lockd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.lockd'; rpc.lockd
;;
esac
case ${rpc_statd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.statd'; rpc.statd
;;
esac
fi
;;
*)
case ${single_mountd_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="-n"
;;
esac
mountd ${mountd_flags}
fi
;;
esac
;;
esac
case ${nfs_client_enable} in
[Yy][Ee][Ss])
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
if [ -n "${nfs_access_cache}" ]; then
echo -n " NFS access cache time=${nfs_access_cache}"
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} >/dev/null
fi
;;
esac
;;
esac
case ${nfs_client_enable} in
[Yy][Ee][Ss])
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
if [ -n "${nfs_access_cache}" ]; then
echo -n " NFS access cache time=${nfs_access_cache}"
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} \
>/dev/null
# If /var/db/mounttab exists, some nfs-server has not been
# sucessfully notified about a previous client shutdown.
# If there is no /var/db/mounttab, we do nothing.
if [ -f /var/db/mounttab ]; then
rpc.umntall -k
fi
;;
esac
# If /var/db/mounttab exists, some nfs-server has not been
# sucessfully notified about a previous client shutdown.
# If there is no /var/db/mounttab, we do nothing.
if [ -f /var/db/mounttab ]; then
rpc.umntall -k
fi
case ${amd_enable} in
[Yy][Ee][Ss])
echo -n ' amd'
case ${amd_map_program} in
[Nn][Oo] | '')
;;
*)
amd_flags="${amd_flags} `eval ${amd_map_program}`"
;;
case ${amd_enable} in
[Yy][Ee][Ss])
echo -n ' amd'
case ${amd_map_program} in
[Nn][Oo] | '')
;;
*)
amd_flags="${amd_flags} `eval\
${amd_map_program}`"
;;
esac
if [ -n "${amd_flags}" ]; then
amd -p ${amd_flags} > /var/run/amd.pid 2> /dev/null
else
amd 2> /dev/null
fi
if [ -n "${amd_flags}" ]; then
amd -p ${amd_flags}\
> /var/run/amd.pid 2> /dev/null
else
amd 2> /dev/null
fi
;;
esac
;;
esac

View File

@ -514,59 +514,61 @@ network_pass2() {
case ${portmap_enable} in
[Yy][Ee][Ss])
echo -n ' portmap'; ${portmap_program:-/usr/sbin/portmap} ${portmap_flags}
;;
esac
echo -n ' rpcbind'; ${portmap_program:-/usr/sbin/rpcbind} \
${portmap_flags}
# Start ypserv if we're an NIS server.
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
#
case ${nis_server_enable} in
[Yy][Ee][Ss])
echo -n ' ypserv'; ypserv ${nis_server_flags}
case ${nis_ypxfrd_enable} in
# Start ypserv if we're an NIS server.
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
#
case ${nis_server_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypxfrd'
rpc.ypxfrd ${nis_ypxfrd_flags}
echo -n ' ypserv'; ypserv ${nis_server_flags}
case ${nis_ypxfrd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypxfrd'
rpc.ypxfrd ${nis_ypxfrd_flags}
;;
esac
case ${nis_yppasswdd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.yppasswdd'
rpc.yppasswdd ${nis_yppasswdd_flags}
;;
esac
;;
esac
case ${nis_yppasswdd_enable} in
# Start ypbind if we're an NIS client
#
case ${nis_client_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.yppasswdd'
rpc.yppasswdd ${nis_yppasswdd_flags}
echo -n ' ypbind'; ypbind ${nis_client_flags}
case ${nis_ypset_enable} in
[Yy][Ee][Ss])
echo -n ' ypset'; ypset ${nis_ypset_flags}
;;
esac
;;
esac
;;
esac
# Start ypbind if we're an NIS client
#
case ${nis_client_enable} in
[Yy][Ee][Ss])
echo -n ' ypbind'; ypbind ${nis_client_flags}
case ${nis_ypset_enable} in
# Start keyserv if we are running Secure RPC
#
case ${keyserv_enable} in
[Yy][Ee][Ss])
echo -n ' ypset'; ypset ${nis_ypset_flags}
echo -n ' keyserv'; keyserv ${keyserv_flags}
;;
esac
;;
esac
# Start keyserv if we are running Secure RPC
#
case ${keyserv_enable} in
[Yy][Ee][Ss])
echo -n ' keyserv'; keyserv ${keyserv_flags}
;;
esac
# Start ypupdated if we are running Secure RPC and we are NIS master
#
case ${rpc_ypupdated_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypupdated'; rpc.ypupdated
# Start ypupdated if we are running Secure RPC
# and we are NIS master
#
case ${rpc_ypupdated_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypupdated'; rpc.ypupdated
;;
esac
;;
esac
@ -582,99 +584,103 @@ network_pass2() {
network_pass3() {
echo -n 'Starting final network daemons:'
case ${nfs_server_enable} in
case ${portmap_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="${mountd_flags} -n"
;;
esac
mountd ${mountd_flags}
case ${nfs_reserved_port_only} in
[Yy][Ee][Ss])
echo -n ' NFS on reserved port only=YES'
sysctl -w vfs.nfs.nfs_privport=1 >/dev/null
;;
esac
echo -n ' nfsd'; nfsd ${nfs_server_flags}
if [ -n "${nfs_bufpackets}" ]; then
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} \
> /dev/null
fi
case ${rpc_lockd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.lockd'; rpc.lockd
;;
esac
case ${rpc_statd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.statd'; rpc.statd
;;
esac
fi
;;
*)
case ${single_mountd_enable} in
case ${nfs_server_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="-n"
mountd_flags="${mountd_flags} -n"
;;
esac
mountd ${mountd_flags}
case ${nfs_reserved_port_only} in
[Yy][Ee][Ss])
echo -n ' NFS on reserved port only=YES'
sysctl -w vfs.nfs.nfs_privport=1 > /dev/null
;;
esac
echo -n ' nfsd'; nfsd ${nfs_server_flags}
if [ -n "${nfs_bufpackets}" ]; then
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} > /dev/null
fi
case ${rpc_lockd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.lockd'; rpc.lockd
;;
esac
case ${rpc_statd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.statd'; rpc.statd
;;
esac
fi
;;
*)
case ${single_mountd_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="-n"
;;
esac
mountd ${mountd_flags}
fi
;;
esac
;;
esac
case ${nfs_client_enable} in
[Yy][Ee][Ss])
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
if [ -n "${nfs_access_cache}" ]; then
echo -n " NFS access cache time=${nfs_access_cache}"
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} >/dev/null
fi
;;
esac
;;
esac
case ${nfs_client_enable} in
[Yy][Ee][Ss])
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
if [ -n "${nfs_access_cache}" ]; then
echo -n " NFS access cache time=${nfs_access_cache}"
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} \
>/dev/null
# If /var/db/mounttab exists, some nfs-server has not been
# sucessfully notified about a previous client shutdown.
# If there is no /var/db/mounttab, we do nothing.
if [ -f /var/db/mounttab ]; then
rpc.umntall -k
fi
;;
esac
# If /var/db/mounttab exists, some nfs-server has not been
# sucessfully notified about a previous client shutdown.
# If there is no /var/db/mounttab, we do nothing.
if [ -f /var/db/mounttab ]; then
rpc.umntall -k
fi
case ${amd_enable} in
[Yy][Ee][Ss])
echo -n ' amd'
case ${amd_map_program} in
[Nn][Oo] | '')
;;
*)
amd_flags="${amd_flags} `eval ${amd_map_program}`"
;;
case ${amd_enable} in
[Yy][Ee][Ss])
echo -n ' amd'
case ${amd_map_program} in
[Nn][Oo] | '')
;;
*)
amd_flags="${amd_flags} `eval\
${amd_map_program}`"
;;
esac
if [ -n "${amd_flags}" ]; then
amd -p ${amd_flags} > /var/run/amd.pid 2> /dev/null
else
amd 2> /dev/null
fi
if [ -n "${amd_flags}" ]; then
amd -p ${amd_flags}\
> /var/run/amd.pid 2> /dev/null
else
amd 2> /dev/null
fi
;;
esac
;;
esac

View File

@ -514,59 +514,61 @@ network_pass2() {
case ${portmap_enable} in
[Yy][Ee][Ss])
echo -n ' portmap'; ${portmap_program:-/usr/sbin/portmap} ${portmap_flags}
;;
esac
echo -n ' rpcbind'; ${portmap_program:-/usr/sbin/rpcbind} \
${portmap_flags}
# Start ypserv if we're an NIS server.
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
#
case ${nis_server_enable} in
[Yy][Ee][Ss])
echo -n ' ypserv'; ypserv ${nis_server_flags}
case ${nis_ypxfrd_enable} in
# Start ypserv if we're an NIS server.
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
#
case ${nis_server_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypxfrd'
rpc.ypxfrd ${nis_ypxfrd_flags}
echo -n ' ypserv'; ypserv ${nis_server_flags}
case ${nis_ypxfrd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypxfrd'
rpc.ypxfrd ${nis_ypxfrd_flags}
;;
esac
case ${nis_yppasswdd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.yppasswdd'
rpc.yppasswdd ${nis_yppasswdd_flags}
;;
esac
;;
esac
case ${nis_yppasswdd_enable} in
# Start ypbind if we're an NIS client
#
case ${nis_client_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.yppasswdd'
rpc.yppasswdd ${nis_yppasswdd_flags}
echo -n ' ypbind'; ypbind ${nis_client_flags}
case ${nis_ypset_enable} in
[Yy][Ee][Ss])
echo -n ' ypset'; ypset ${nis_ypset_flags}
;;
esac
;;
esac
;;
esac
# Start ypbind if we're an NIS client
#
case ${nis_client_enable} in
[Yy][Ee][Ss])
echo -n ' ypbind'; ypbind ${nis_client_flags}
case ${nis_ypset_enable} in
# Start keyserv if we are running Secure RPC
#
case ${keyserv_enable} in
[Yy][Ee][Ss])
echo -n ' ypset'; ypset ${nis_ypset_flags}
echo -n ' keyserv'; keyserv ${keyserv_flags}
;;
esac
;;
esac
# Start keyserv if we are running Secure RPC
#
case ${keyserv_enable} in
[Yy][Ee][Ss])
echo -n ' keyserv'; keyserv ${keyserv_flags}
;;
esac
# Start ypupdated if we are running Secure RPC and we are NIS master
#
case ${rpc_ypupdated_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypupdated'; rpc.ypupdated
# Start ypupdated if we are running Secure RPC
# and we are NIS master
#
case ${rpc_ypupdated_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypupdated'; rpc.ypupdated
;;
esac
;;
esac
@ -582,99 +584,103 @@ network_pass2() {
network_pass3() {
echo -n 'Starting final network daemons:'
case ${nfs_server_enable} in
case ${portmap_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="${mountd_flags} -n"
;;
esac
mountd ${mountd_flags}
case ${nfs_reserved_port_only} in
[Yy][Ee][Ss])
echo -n ' NFS on reserved port only=YES'
sysctl -w vfs.nfs.nfs_privport=1 >/dev/null
;;
esac
echo -n ' nfsd'; nfsd ${nfs_server_flags}
if [ -n "${nfs_bufpackets}" ]; then
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} \
> /dev/null
fi
case ${rpc_lockd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.lockd'; rpc.lockd
;;
esac
case ${rpc_statd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.statd'; rpc.statd
;;
esac
fi
;;
*)
case ${single_mountd_enable} in
case ${nfs_server_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="-n"
mountd_flags="${mountd_flags} -n"
;;
esac
mountd ${mountd_flags}
case ${nfs_reserved_port_only} in
[Yy][Ee][Ss])
echo -n ' NFS on reserved port only=YES'
sysctl -w vfs.nfs.nfs_privport=1 > /dev/null
;;
esac
echo -n ' nfsd'; nfsd ${nfs_server_flags}
if [ -n "${nfs_bufpackets}" ]; then
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} > /dev/null
fi
case ${rpc_lockd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.lockd'; rpc.lockd
;;
esac
case ${rpc_statd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.statd'; rpc.statd
;;
esac
fi
;;
*)
case ${single_mountd_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="-n"
;;
esac
mountd ${mountd_flags}
fi
;;
esac
;;
esac
case ${nfs_client_enable} in
[Yy][Ee][Ss])
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
if [ -n "${nfs_access_cache}" ]; then
echo -n " NFS access cache time=${nfs_access_cache}"
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} >/dev/null
fi
;;
esac
;;
esac
case ${nfs_client_enable} in
[Yy][Ee][Ss])
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
if [ -n "${nfs_access_cache}" ]; then
echo -n " NFS access cache time=${nfs_access_cache}"
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} \
>/dev/null
# If /var/db/mounttab exists, some nfs-server has not been
# sucessfully notified about a previous client shutdown.
# If there is no /var/db/mounttab, we do nothing.
if [ -f /var/db/mounttab ]; then
rpc.umntall -k
fi
;;
esac
# If /var/db/mounttab exists, some nfs-server has not been
# sucessfully notified about a previous client shutdown.
# If there is no /var/db/mounttab, we do nothing.
if [ -f /var/db/mounttab ]; then
rpc.umntall -k
fi
case ${amd_enable} in
[Yy][Ee][Ss])
echo -n ' amd'
case ${amd_map_program} in
[Nn][Oo] | '')
;;
*)
amd_flags="${amd_flags} `eval ${amd_map_program}`"
;;
case ${amd_enable} in
[Yy][Ee][Ss])
echo -n ' amd'
case ${amd_map_program} in
[Nn][Oo] | '')
;;
*)
amd_flags="${amd_flags} `eval\
${amd_map_program}`"
;;
esac
if [ -n "${amd_flags}" ]; then
amd -p ${amd_flags} > /var/run/amd.pid 2> /dev/null
else
amd 2> /dev/null
fi
if [ -n "${amd_flags}" ]; then
amd -p ${amd_flags}\
> /var/run/amd.pid 2> /dev/null
else
amd 2> /dev/null
fi
;;
esac
;;
esac

View File

@ -514,59 +514,61 @@ network_pass2() {
case ${portmap_enable} in
[Yy][Ee][Ss])
echo -n ' portmap'; ${portmap_program:-/usr/sbin/portmap} ${portmap_flags}
;;
esac
echo -n ' rpcbind'; ${portmap_program:-/usr/sbin/rpcbind} \
${portmap_flags}
# Start ypserv if we're an NIS server.
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
#
case ${nis_server_enable} in
[Yy][Ee][Ss])
echo -n ' ypserv'; ypserv ${nis_server_flags}
case ${nis_ypxfrd_enable} in
# Start ypserv if we're an NIS server.
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
#
case ${nis_server_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypxfrd'
rpc.ypxfrd ${nis_ypxfrd_flags}
echo -n ' ypserv'; ypserv ${nis_server_flags}
case ${nis_ypxfrd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypxfrd'
rpc.ypxfrd ${nis_ypxfrd_flags}
;;
esac
case ${nis_yppasswdd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.yppasswdd'
rpc.yppasswdd ${nis_yppasswdd_flags}
;;
esac
;;
esac
case ${nis_yppasswdd_enable} in
# Start ypbind if we're an NIS client
#
case ${nis_client_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.yppasswdd'
rpc.yppasswdd ${nis_yppasswdd_flags}
echo -n ' ypbind'; ypbind ${nis_client_flags}
case ${nis_ypset_enable} in
[Yy][Ee][Ss])
echo -n ' ypset'; ypset ${nis_ypset_flags}
;;
esac
;;
esac
;;
esac
# Start ypbind if we're an NIS client
#
case ${nis_client_enable} in
[Yy][Ee][Ss])
echo -n ' ypbind'; ypbind ${nis_client_flags}
case ${nis_ypset_enable} in
# Start keyserv if we are running Secure RPC
#
case ${keyserv_enable} in
[Yy][Ee][Ss])
echo -n ' ypset'; ypset ${nis_ypset_flags}
echo -n ' keyserv'; keyserv ${keyserv_flags}
;;
esac
;;
esac
# Start keyserv if we are running Secure RPC
#
case ${keyserv_enable} in
[Yy][Ee][Ss])
echo -n ' keyserv'; keyserv ${keyserv_flags}
;;
esac
# Start ypupdated if we are running Secure RPC and we are NIS master
#
case ${rpc_ypupdated_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypupdated'; rpc.ypupdated
# Start ypupdated if we are running Secure RPC
# and we are NIS master
#
case ${rpc_ypupdated_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.ypupdated'; rpc.ypupdated
;;
esac
;;
esac
@ -582,99 +584,103 @@ network_pass2() {
network_pass3() {
echo -n 'Starting final network daemons:'
case ${nfs_server_enable} in
case ${portmap_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="${mountd_flags} -n"
;;
esac
mountd ${mountd_flags}
case ${nfs_reserved_port_only} in
[Yy][Ee][Ss])
echo -n ' NFS on reserved port only=YES'
sysctl -w vfs.nfs.nfs_privport=1 >/dev/null
;;
esac
echo -n ' nfsd'; nfsd ${nfs_server_flags}
if [ -n "${nfs_bufpackets}" ]; then
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} \
> /dev/null
fi
case ${rpc_lockd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.lockd'; rpc.lockd
;;
esac
case ${rpc_statd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.statd'; rpc.statd
;;
esac
fi
;;
*)
case ${single_mountd_enable} in
case ${nfs_server_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="-n"
mountd_flags="${mountd_flags} -n"
;;
esac
mountd ${mountd_flags}
case ${nfs_reserved_port_only} in
[Yy][Ee][Ss])
echo -n ' NFS on reserved port only=YES'
sysctl -w vfs.nfs.nfs_privport=1 > /dev/null
;;
esac
echo -n ' nfsd'; nfsd ${nfs_server_flags}
if [ -n "${nfs_bufpackets}" ]; then
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} > /dev/null
fi
case ${rpc_lockd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.lockd'; rpc.lockd
;;
esac
case ${rpc_statd_enable} in
[Yy][Ee][Ss])
echo -n ' rpc.statd'; rpc.statd
;;
esac
fi
;;
*)
case ${single_mountd_enable} in
[Yy][Ee][Ss])
if [ -r /etc/exports ]; then
echo -n ' mountd'
case ${weak_mountd_authentication} in
[Yy][Ee][Ss])
mountd_flags="-n"
;;
esac
mountd ${mountd_flags}
fi
;;
esac
;;
esac
case ${nfs_client_enable} in
[Yy][Ee][Ss])
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
if [ -n "${nfs_access_cache}" ]; then
echo -n " NFS access cache time=${nfs_access_cache}"
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} >/dev/null
fi
;;
esac
;;
esac
case ${nfs_client_enable} in
[Yy][Ee][Ss])
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
if [ -n "${nfs_access_cache}" ]; then
echo -n " NFS access cache time=${nfs_access_cache}"
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} \
>/dev/null
# If /var/db/mounttab exists, some nfs-server has not been
# sucessfully notified about a previous client shutdown.
# If there is no /var/db/mounttab, we do nothing.
if [ -f /var/db/mounttab ]; then
rpc.umntall -k
fi
;;
esac
# If /var/db/mounttab exists, some nfs-server has not been
# sucessfully notified about a previous client shutdown.
# If there is no /var/db/mounttab, we do nothing.
if [ -f /var/db/mounttab ]; then
rpc.umntall -k
fi
case ${amd_enable} in
[Yy][Ee][Ss])
echo -n ' amd'
case ${amd_map_program} in
[Nn][Oo] | '')
;;
*)
amd_flags="${amd_flags} `eval ${amd_map_program}`"
;;
case ${amd_enable} in
[Yy][Ee][Ss])
echo -n ' amd'
case ${amd_map_program} in
[Nn][Oo] | '')
;;
*)
amd_flags="${amd_flags} `eval\
${amd_map_program}`"
;;
esac
if [ -n "${amd_flags}" ]; then
amd -p ${amd_flags} > /var/run/amd.pid 2> /dev/null
else
amd 2> /dev/null
fi
if [ -n "${amd_flags}" ]; then
amd -p ${amd_flags}\
> /var/run/amd.pid 2> /dev/null
else
amd 2> /dev/null
fi
;;
esac
;;
esac

37
etc/rpc
View File

@ -1,8 +1,8 @@
#
# $FreeBSD$
# rpc 88/08/01 4.0 RPCSRC; from 1.12 88/02/07 SMI
# rpc 88/08/01 4.0 RPCSRC; from 1.12 99/07/25 SMI
#
portmapper 100000 portmap sunrpc
rpcbind 100000 portmap sunrpc rpcbind
rstatd 100001 rstat rstat_svc rup perfmeter
rusersd 100002 rusers
nfs 100003 nfsprog
@ -29,10 +29,39 @@ status 100024
bootparamd 100026 bootparam
ypupdated 100028 ypupdate
keyserv 100029 keyserver
sunlink_mapper 100033
tfsd 100037
nsed 100038
nsemntd 100039
showfhd 100043 showfh
ioadmd 100055 rpc.ioadmd
NETlicense 100062
sunisamd 100065
debug_svc 100066 dbsrv
cmsd 100068
bugtraqd 100071
kerbd 100078
ttdbserver 100083 tooltalk
event 100101 na.event # SunNet Manager
logger 100102 na.logger # SunNet Manager
sync 100104 na.sync
hostperf 100107 na.hostperf
activity 100109 na.activity # SunNet Manager
hostmem 100112 na.hostmem
sample 100113 na.sample
x25 100114 na.x25
ping 100115 na.ping
rpcnfs 100116 na.rpcnfs
hostif 100117 na.hostif
etherif 100118 na.etherif
iproutes 100120 na.iproutes
layers 100121 na.layers
snmp 100122 na.snmp snmp-cmc snmp-synoptics snmp-unisys snmp-utk
traffic 100123 na.traffic
nfs_acl 100227
sadmind 100232
nisd 100300 rpc.nisd
nispasswd 100303 rpc.nispasswdd
ufsd 100233 ufsd
pcnfsd 150001 pcnfs
amd 300019
cmsd 100068
ttdbserver 100083 tooltalk

View File

@ -7,13 +7,13 @@
# links.
CLEANFILES= osreldate.h version vers.c
SUBDIR= rpcsvc
SUBDIR= rpcsvc rpc
FILES= a.out.h ar.h assert.h bitstring.h ctype.h db.h dirent.h disktab.h \
dlfcn.h elf.h err.h fnmatch.h fstab.h \
fts.h glob.h grp.h strhash.h \
hesiod.h histedit.h ieeefp.h ifaddrs.h iso646.h langinfo.h \
libgen.h limits.h link.h locale.h malloc.h memory.h mpool.h \
ndbm.h netdb.h nl_types.h nlist.h nsswitch.h objformat.h \
netconfig.h ndbm.h netdb.h nl_types.h nlist.h nsswitch.h objformat.h \
paths.h pthread.h pthread_np.h pwd.h \
ranlib.h regex.h regexp.h resolv.h rune.h runetype.h \
search.h setjmp.h sgtty.h \
@ -28,10 +28,6 @@ ARPAFILES= ftp.h inet.h nameser.h nameser_compat.h telnet.h tftp.h
PROTOFILES= dumprestore.h routed.h rwhod.h talkd.h timed.h
RPCFILES= auth.h auth_unix.h clnt.h pmap_clnt.h pmap_prot.h pmap_rmt.h \
rpc.h rpc_com.h rpc_msg.h svc.h svc_auth.h types.h xdr.h \
auth_des.h des.h des_crypt.h
MFILES= float.h floatingpoint.h stdarg.h varargs.h
# posix4/aio.h conflicts with dysons and isn't installed:
@ -86,9 +82,6 @@ beforeinstall: ${SHARED}
cd ${.CURDIR}/protocols; \
${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
${PROTOFILES} ${DESTDIR}/usr/include/protocols
cd ${.CURDIR}/rpc; \
${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
${RPCFILES} ${DESTDIR}/usr/include/rpc
${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
${.OBJDIR}/osreldate.h \
${DESTDIR}/usr/include

96
include/netconfig.h Normal file
View File

@ -0,0 +1,96 @@
/* $NetBSD: netconfig.h,v 1.1 2000/06/02 22:57:54 fvdl Exp $ */
/* $FreeBSD$ */
#ifndef _NETCONFIG_H_
#define _NETCONFIG_H_
#include <sys/cdefs.h>
#define NETCONFIG "/etc/netconfig"
#define NETPATH "NETPATH"
struct netconfig {
char *nc_netid; /* Network ID */
unsigned long nc_semantics; /* Semantics (see below) */
unsigned long nc_flag; /* Flags (see below) */
char *nc_protofmly; /* Protocol family */
char *nc_proto; /* Protocol name */
char *nc_device; /* Network device pathname */
unsigned long nc_nlookups; /* Number of directory lookup libs */
char **nc_lookups; /* Names of the libraries */
unsigned long nc_unused[9]; /* reserved */
};
typedef struct {
struct netconfig **nc_head;
struct netconfig **nc_curr;
} NCONF_HANDLE;
/*
* nc_semantics values
*/
#define NC_TPI_CLTS 1
#define NC_TPI_COTS 2
#define NC_TPI_COTS_ORD 3
#define NC_TPI_RAW 4
/*
* nc_flag values
*/
#define NC_NOFLAG 0x00
#define NC_VISIBLE 0x01
#define NC_BROADCAST 0x02
/*
* nc_protofmly values
*/
#define NC_NOPROTOFMLY "-"
#define NC_LOOPBACK "loopback"
#define NC_INET "inet"
#define NC_INET6 "inet6"
#define NC_IMPLINK "implink"
#define NC_PUP "pup"
#define NC_CHAOS "chaos"
#define NC_NS "ns"
#define NC_NBS "nbs"
#define NC_ECMA "ecma"
#define NC_DATAKIT "datakit"
#define NC_CCITT "ccitt"
#define NC_SNA "sna"
#define NC_DECNET "decnet"
#define NC_DLI "dli"
#define NC_LAT "lat"
#define NC_HYLINK "hylink"
#define NC_APPLETALK "appletalk"
#define NC_NIT "nit"
#define NC_IEEE802 "ieee802"
#define NC_OSI "osi"
#define NC_X25 "x25"
#define NC_OSINET "osinet"
#define NC_GOSIP "gosip"
/*
* nc_proto values
*/
#define NC_NOPROTO "-"
#define NC_TCP "tcp"
#define NC_UDP "udp"
#define NC_ICMP "icmp"
__BEGIN_DECLS
void *setnetconfig __P((void));
struct netconfig *getnetconfig __P((void *));
struct netconfig *getnetconfigent __P((char *));
void freenetconfigent __P((struct netconfig *));
int endnetconfig __P((void *));
void *setnetpath __P((void));
struct netconfig *getnetpath __P((void *));
int endnetpath(void *);
void nc_perror __P((const char *));
char *nc_sperror __P((void));
__END_DECLS
#endif /* _NETCONFIG_H_ */

View File

@ -29,6 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _PTHREAD_NP_H_
#define _PTHREAD_NP_H_
@ -52,6 +53,7 @@ int pthread_mutexattr_setkind_np __P((pthread_mutexattr_t *, int));
void pthread_set_name_np __P((pthread_t, char *));
int pthread_switch_add_np __P((pthread_switch_routine_t));
int pthread_switch_delete_np __P((pthread_switch_routine_t));
int pthread_main_np __P((void));
__END_DECLS
#endif

37
include/rpc/Makefile Normal file
View File

@ -0,0 +1,37 @@
# from: @(#)Makefile 2.3 88/08/11 4.0 RPCSRC
# $FreeBSD$
.SUFFIXES: .x
RPCCOM = rpcgen -C
HDRS= rpcb_prot.h
XFILES= rpcb_prot.x
HFILES= auth.h auth_unix.h clnt.h clnt_soc.h clnt_stat.h \
nettype.h pmap_clnt.h pmap_prot.h pmap_rmt.h raw.h \
rpc.h rpc_msg.h rpcb_clnt.h rpcent.h rpc_com.h \
svc.h svc_auth.h svc_soc.h svc_dg.h types.h xdr.h
# Secure RPC
HFILES+= auth_des.h des.h des_crypt.h
# Kerberos
HFILES+= auth_kerb.h
CLEANFILES+= ${HDRS}
all: ${HDRS}
beforeinstall:
${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
${HFILES:S;^;${.CURDIR}/;} \
${XFILES:S;^;${.CURDIR}/;} \
${HDRS} \
${DESTDIR}/usr/include/rpc
.x.h:
${RPCCOM} -h -DWANT_NFS3 ${.IMPSRC} -o ${.TARGET}
.include <bsd.prog.mk>

View File

@ -1,3 +1,5 @@
/* $NetBSD: auth.h,v 1.15 2000/06/02 22:57:55 fvdl Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -28,6 +30,7 @@
*
* from: @(#)auth.h 1.17 88/02/08 SMI
* from: @(#)auth.h 2.3 88/08/07 4.0 RPCSRC
* from: @(#)auth.h 1.43 98/02/02 SMI
* $FreeBSD$
*/
@ -43,12 +46,75 @@
#ifndef _RPC_AUTH_H
#define _RPC_AUTH_H
#include <rpc/xdr.h>
#include <rpc/clnt_stat.h>
#include <sys/cdefs.h>
#include <sys/socket.h>
#define MAX_AUTH_BYTES 400
#define MAXNETNAMELEN 255 /* maximum length of network user's name */
/*
* Client side authentication/security data
*/
typedef struct sec_data {
u_int secmod; /* security mode number e.g. in nfssec.conf */
u_int rpcflavor; /* rpc flavors:AUTH_UNIX,AUTH_DES,RPCSEC_GSS */
int flags; /* AUTH_F_xxx flags */
caddr_t data; /* opaque data per flavor */
} sec_data_t;
#ifdef _SYSCALL32_IMPL
struct sec_data32 {
uint32_t secmod; /* security mode number e.g. in nfssec.conf */
uint32_t rpcflavor; /* rpc flavors:AUTH_UNIX,AUTH_DES,RPCSEC_GSS */
int32_t flags; /* AUTH_F_xxx flags */
caddr32_t data; /* opaque data per flavor */
};
#endif /* _SYSCALL32_IMPL */
/*
* AUTH_DES flavor specific data from sec_data opaque data field.
* AUTH_KERB has the same structure.
*/
typedef struct des_clnt_data {
struct netbuf syncaddr; /* time sync addr */
struct knetconfig *knconf; /* knetconfig info that associated */
/* with the syncaddr. */
char *netname; /* server's netname */
int netnamelen; /* server's netname len */
} dh_k4_clntdata_t;
#ifdef _SYSCALL32_IMPL
struct des_clnt_data32 {
struct netbuf32 syncaddr; /* time sync addr */
caddr32_t knconf; /* knetconfig info that associated */
/* with the syncaddr. */
caddr32_t netname; /* server's netname */
int32_t netnamelen; /* server's netname len */
};
#endif /* _SYSCALL32_IMPL */
#ifdef KERBEROS
/*
* flavor specific data to hold the data for AUTH_DES/AUTH_KERB(v4)
* in sec_data->data opaque field.
*/
typedef struct krb4_svc_data {
int window; /* window option value */
} krb4_svcdata_t;
typedef struct krb4_svc_data des_svcdata_t;
#endif /* KERBEROS */
/*
* authentication/security specific flags
*/
#define AUTH_F_RPCTIMESYNC 0x001 /* use RPC to do time sync */
#define AUTH_F_TRYNONE 0x002 /* allow fall back to AUTH_NONE */
/*
* Status returned from authentication check
*/
@ -67,18 +133,32 @@ enum auth_stat {
*/
AUTH_INVALIDRESP=6, /* bogus response verifier */
AUTH_FAILED=7 /* some unknown reason */
#ifdef KERBEROS
/*
* kerberos errors
*/
AUTH_KERB_GENERIC = 8, /* kerberos generic error */
AUTH_TIMEEXPIRE = 9, /* time of credential expired */
AUTH_TKT_FILE = 10, /* something wrong with ticket file */
AUTH_DECODE = 11, /* can't decode authenticator */
AUTH_NET_ADDR = 12 /* wrong net address in ticket */
#endif /* KERBEROS */
};
union des_block {
struct {
u_int32_t high;
u_int32_t low;
uint32_t high;
uint32_t low;
} key;
char c[8];
};
typedef union des_block des_block;
__BEGIN_DECLS
extern bool_t xdr_des_block __P((XDR *, des_block *));
#ifdef __STDC__
extern bool_t xdr_des_block(XDR *, des_block *);
#else
extern bool_t xdr_des_block();
#endif
__END_DECLS
/*
@ -89,29 +169,26 @@ struct opaque_auth {
caddr_t oa_base; /* address of more auth stuff */
u_int oa_length; /* not to exceed MAX_AUTH_BYTES */
};
__BEGIN_DECLS
bool_t xdr_opaque_auth __P((XDR *xdrs, struct opaque_auth *ap));
__END_DECLS
/*
* Auth handle, interface to client side authenticators.
*/
typedef struct __rpc_auth {
typedef struct __auth {
struct opaque_auth ah_cred;
struct opaque_auth ah_verf;
union des_block ah_key;
struct auth_ops {
void (*ah_nextverf) __P((struct __rpc_auth *));
void (*ah_nextverf) (struct __auth *);
/* nextverf & serialize */
int (*ah_marshal) __P((struct __rpc_auth *, XDR *));
int (*ah_marshal) (struct __auth *, XDR *);
/* validate verifier */
int (*ah_validate) __P((struct __rpc_auth *,
struct opaque_auth *));
int (*ah_validate) (struct __auth *,
struct opaque_auth *);
/* refresh credentials */
int (*ah_refresh) __P((struct __rpc_auth *));
int (*ah_refresh) (struct __auth *, void *);
/* destroy this structure */
void (*ah_destroy) __P((struct __rpc_auth *));
void (*ah_destroy) (struct __auth *);
} *ah_ops;
caddr_t ah_private;
} AUTH;
@ -140,10 +217,10 @@ typedef struct __rpc_auth {
#define auth_validate(auth, verfp) \
((*((auth)->ah_ops->ah_validate))((auth), verfp))
#define AUTH_REFRESH(auth) \
((*((auth)->ah_ops->ah_refresh))(auth))
#define auth_refresh(auth) \
((*((auth)->ah_ops->ah_refresh))(auth))
#define AUTH_REFRESH(auth, msg) \
((*((auth)->ah_ops->ah_refresh))(auth, msg))
#define auth_refresh(auth, msg) \
((*((auth)->ah_ops->ah_refresh))(auth, msg))
#define AUTH_DESTROY(auth) \
((*((auth)->ah_ops->ah_destroy))(auth))
@ -151,14 +228,16 @@ typedef struct __rpc_auth {
((*((auth)->ah_ops->ah_destroy))(auth))
__BEGIN_DECLS
extern struct opaque_auth _null_auth;
__END_DECLS
/*
* These are the various implementations of client side authenticators.
*/
/*
* Unix style authentication
* System style authentication
* AUTH *authunix_create(machname, uid, gid, len, aup_gids)
* char *machname;
* int uid;
@ -167,94 +246,105 @@ extern struct opaque_auth _null_auth;
* int *aup_gids;
*/
__BEGIN_DECLS
struct sockaddr_in;
extern AUTH *authunix_create __P((char *, int, int, int, int *));
extern AUTH *authunix_create_default __P((void));
extern AUTH *authnone_create __P((void));
extern AUTH *authunix_create(char *, int, int, int,
int *);
extern AUTH *authunix_create_default(void); /* takes no parameters */
extern AUTH *authnone_create(void); /* takes no parameters */
__END_DECLS
/* Forward compatibility with TI-RPC */
#define authsys_create authunix_create
#define authsys_create_default authunix_create_default
/*
* DES style authentication
* AUTH *authdes_create(servername, window, timehost, ckey)
* AUTH *authsecdes_create(servername, window, timehost, ckey)
* char *servername; - network name of server
* u_int window; - time to live
* struct sockaddr *timehost; - optional hostname to sync with
* const char *timehost; - optional hostname to sync with
* des_block *ckey; - optional conversation key to use
*/
__BEGIN_DECLS
extern AUTH *authdes_create __P(( char *, u_int, struct sockaddr *, des_block * ));
#ifdef NOTYET
/*
* TI-RPC supports this call, but it requires the inclusion of
* NIS+-specific headers which would require the inclusion of other
* headers which would result in a tangled mess. For now, the NIS+
* code prototypes this routine internally.
*/
extern AUTH *authdes_pk_create __P(( char *, netobj *, u_int,
struct sockaddr *, des_block *,
nis_server * ));
#endif
extern AUTH *authdes_create (char *, u_int, struct sockaddr *, des_block *);
extern AUTH *authdes_seccreate (const char *, const u_int, const char *,
const des_block *);
__END_DECLS
__BEGIN_DECLS
extern bool_t xdr_opaque_auth __P((XDR *, struct opaque_auth *));
__END_DECLS
#define authsys_create(c,i1,i2,i3,ip) authunix_create((c),(i1),(i2),(i3),(ip))
#define authsys_create_default() authunix_create_default()
/*
* Netname manipulation routines.
*/
__BEGIN_DECLS
extern int netname2user __P(( char *, uid_t *, gid_t *, int *, gid_t *));
extern int netname2host __P(( char *, char *, int ));
extern int getnetname __P(( char * ));
extern int user2netname __P(( char *, uid_t, char * ));
extern int host2netname __P(( char *, char *, char * ));
extern void passwd2des __P(( char *, char * ));
extern int getnetname(char *);
extern int host2netname(char *, const char *, const char *);
extern int user2netname(char *, const uid_t, const char *);
extern int netname2user(char *, uid_t *, gid_t *, int *, gid_t *);
extern int netname2host(char *, char *, const int);
extern void passwd2des ( char *, char * );
__END_DECLS
/*
* Keyserv interface routines.
* XXX Should not be here.
*
* These routines interface to the keyserv daemon
*
*/
#ifndef HEXKEYBYTES
#define HEXKEYBYTES 48
#endif
typedef char kbuf[HEXKEYBYTES];
typedef char *namestr;
struct netstarg {
kbuf st_priv_key;
kbuf st_pub_key;
namestr st_netname;
};
__BEGIN_DECLS
extern int key_decryptsession __P(( const char *, des_block * ));
extern int key_decryptsession_pk __P(( char *, netobj *, des_block * ));
extern int key_encryptsession __P(( const char *, des_block * ));
extern int key_encryptsession_pk __P(( char *, netobj *, des_block * ));
extern int key_gendes __P(( des_block * ));
extern int key_setsecret __P(( const char * ));
extern int key_secretkey_is_set __P(( void ));
extern int key_setnet __P(( struct netstarg * ));
extern int key_get_conv __P(( char *, des_block * ));
extern int key_decryptsession(const char *, des_block *);
extern int key_encryptsession(const char *, des_block *);
extern int key_gendes(des_block *);
extern int key_setsecret(const char *);
extern int key_secretkey_is_set(void);
__END_DECLS
#ifdef KERBEROS
/*
* Kerberos style authentication
* AUTH *authkerb_seccreate(service, srv_inst, realm, window, timehost, status)
* const char *service; - service name
* const char *srv_inst; - server instance
* const char *realm; - server realm
* const u_int window; - time to live
* const char *timehost; - optional hostname to sync with
* int *status; - kerberos status returned
*/
__BEGIN_DECLS
extern AUTH *authkerb_seccreate(const char *, const char *, const char *,
const u_int, const char *, int *);
__END_DECLS
/*
* Publickey routines.
* Map a kerberos credential into a unix cred.
*
* authkerb_getucred(rqst, uid, gid, grouplen, groups)
* const struct svc_req *rqst; - request pointer
* uid_t *uid;
* gid_t *gid;
* short *grouplen;
* int *groups;
*
*/
__BEGIN_DECLS
extern int getpublickey __P(( char *, char * ));
extern int getpublicandprivatekey __P(( char *, char * ));
extern int getsecretkey __P(( char *, char *, char * ));
extern int authkerb_getucred(/* struct svc_req *, uid_t *, gid_t *,
short *, int * */);
__END_DECLS
#endif /* KERBEROS */
__BEGIN_DECLS
struct svc_req;
struct rpc_msg;
enum auth_stat _svcauth_null __P((struct svc_req *, struct rpc_msg *));
enum auth_stat _svcauth_short __P((struct svc_req *, struct rpc_msg *));
enum auth_stat _svcauth_unix __P((struct svc_req *, struct rpc_msg *));
__END_DECLS
#define AUTH_NONE 0 /* no authentication */
#define AUTH_NULL 0 /* backward compatibility */
#define AUTH_UNIX 1 /* unix style (uid, gids) */
#define AUTH_SYS 1 /* forward compatibility */
#define AUTH_SYS 1 /* unix style (uid, gids) */
#define AUTH_UNIX AUTH_SYS
#define AUTH_SHORT 2 /* short hand unix style */
#define AUTH_DES 3 /* des style (encrypted timestamps) */
#define AUTH_DH 3 /* for Diffie-Hellman mechanism */
#define AUTH_DES AUTH_DH /* for backward compatibility */
#define AUTH_KERB 4 /* kerberos style */
#endif /* !_RPC_AUTH_H */

View File

@ -1,4 +1,5 @@
/* @(#)auth_des.h 2.2 88/07/29 4.0 RPCSRC; from 1.3 88/02/08 SMI */
/* $FreeBSD$ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -26,10 +27,13 @@
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*
* from: @(#)auth_des.h 2.2 88/07/29 4.0 RPCSRC
* from: @(#)auth_des.h 1.14 94/04/25 SMI
*/
/*
* Copyright (c) 1988 by Sun Microsystems, Inc.
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
*/
/*
@ -102,8 +106,21 @@ struct authdes_verf {
#define adv_xtimeverf adv_time_u.adv_xtime
#define adv_nickname adv_int_u
/*
* Map a des credential into a unix cred.
*
*/
__BEGIN_DECLS
extern int authdes_getucred __P(( struct authdes_cred *, uid_t *, gid_t *, int *, gid_t * ));
__END_DECLS
__BEGIN_DECLS
extern bool_t xdr_authdes_cred(XDR *, struct authdes_cred *);
extern bool_t xdr_authdes_verf(XDR *, struct authdes_verf *);
extern int rtime(dev_t, struct netbuf *, int, struct timeval *,
struct timeval *);
extern void kgetnetname(char *);
extern enum auth_stat _svcauth_des(struct svc_req *, struct rpc_msg *);
__END_DECLS
#endif /* ndef _AUTH_DES_ */

143
include/rpc/auth_kerb.h Normal file
View File

@ -0,0 +1,143 @@
/* $FreeBSD$ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* auth_kerb.h, Protocol for Kerberos style authentication for RPC
*
* Copyright (C) 1986, Sun Microsystems, Inc.
*/
#ifndef _RPC_AUTH_KERB_H
#define _RPC_AUTH_KERB_H
#ifdef KERBEROS
#pragma ident "@(#)auth_kerb.h 1.10 94/04/25 SMI"
#include <kerberos/krb.h>
#include <sys/socket.h>
#include <sys/t_kuser.h>
#include <netinet/in.h>
#include <rpc/svc.h>
/*
* There are two kinds of "names": fullnames and nicknames
*/
enum authkerb_namekind {
AKN_FULLNAME,
AKN_NICKNAME
};
/*
* A fullname contains the ticket and the window
*/
struct authkerb_fullname {
KTEXT_ST ticket;
u_long window; /* associated window */
};
/*
* cooked credential stored in rq_clntcred
*/
struct authkerb_clnt_cred {
/* start of AUTH_DAT */
unsigned char k_flags; /* Flags from ticket */
char pname[ANAME_SZ]; /* Principal's name */
char pinst[INST_SZ]; /* His Instance */
char prealm[REALM_SZ]; /* His Realm */
unsigned long checksum; /* Data checksum (opt) */
C_Block session; /* Session Key */
int life; /* Life of ticket */
unsigned long time_sec; /* Time ticket issued */
unsigned long address; /* Address in ticket */
/* KTEXT_ST reply; Auth reply (opt) */
/* end of AUTH_DAT */
unsigned long expiry; /* time the ticket is expiring */
u_long nickname; /* Nickname into cache */
u_long window; /* associated window */
};
typedef struct authkerb_clnt_cred authkerb_clnt_cred;
/*
* A credential
*/
struct authkerb_cred {
enum authkerb_namekind akc_namekind;
struct authkerb_fullname akc_fullname;
u_long akc_nickname;
};
/*
* A kerb authentication verifier
*/
struct authkerb_verf {
union {
struct timeval akv_ctime; /* clear time */
des_block akv_xtime; /* crypt time */
} akv_time_u;
u_long akv_int_u;
};
/*
* des authentication verifier: client variety
*
* akv_timestamp is the current time.
* akv_winverf is the credential window + 1.
* Both are encrypted using the conversation key.
*/
#ifndef akv_timestamp
#define akv_timestamp akv_time_u.akv_ctime
#define akv_xtimestamp akv_time_u.akv_xtime
#define akv_winverf akv_int_u
#endif
/*
* des authentication verifier: server variety
*
* akv_timeverf is the client's timestamp + client's window
* akv_nickname is the server's nickname for the client.
* akv_timeverf is encrypted using the conversation key.
*/
#ifndef akv_timeverf
#define akv_timeverf akv_time_u.akv_ctime
#define akv_xtimeverf akv_time_u.akv_xtime
#define akv_nickname akv_int_u
#endif
/*
* Register the service name, instance and realm.
*/
extern int authkerb_create(char *, char *, char *, u_int,
struct netbuf *, int *, dev_t, int, AUTH **);
extern bool_t xdr_authkerb_cred(XDR *, struct authkerb_cred *);
extern bool_t xdr_authkerb_verf(XDR *, struct authkerb_verf *);
extern int svc_kerb_reg(SVCXPRT *, char *, char *, char *);
extern enum auth_stat _svcauth_kerb(struct svc_req *, struct rpc_msg *);
#endif KERBEROS
#endif /* !_RPC_AUTH_KERB_H */

View File

@ -1,3 +1,5 @@
/* $NetBSD: clnt.h,v 1.14 2000/06/02 22:57:55 fvdl Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -26,7 +28,7 @@
* 2550 Garcia Avenue
* Mountain View, California 94043
*
* from: @(#)clnt.h 1.31 88/02/08 SMI
* from: @(#)clnt.h 1.31 94/04/29 SMI
* from: @(#)clnt.h 2.1 88/07/29 4.0 RPCSRC
* $FreeBSD$
*/
@ -39,52 +41,28 @@
#ifndef _RPC_CLNT_H_
#define _RPC_CLNT_H_
#include <rpc/clnt_stat.h>
#include <sys/cdefs.h>
#include <netconfig.h>
#include <sys/un.h>
/*
* Rpc calls return an enum clnt_stat. This should be looked at more,
* since each implementation is required to live with this (implementation
* independent) list of errors.
* Well-known IPV6 RPC broadcast address.
*/
enum clnt_stat {
RPC_SUCCESS=0, /* call succeeded */
/*
* local errors
*/
RPC_CANTENCODEARGS=1, /* can't encode arguments */
RPC_CANTDECODERES=2, /* can't decode results */
RPC_CANTSEND=3, /* failure in sending call */
RPC_CANTRECV=4, /* failure in receiving result */
RPC_TIMEDOUT=5, /* call timed out */
/*
* remote errors
*/
RPC_VERSMISMATCH=6, /* rpc versions not compatible */
RPC_AUTHERROR=7, /* authentication error */
RPC_PROGUNAVAIL=8, /* program not available */
RPC_PROGVERSMISMATCH=9, /* program version mismatched */
RPC_PROCUNAVAIL=10, /* procedure unavailable */
RPC_CANTDECODEARGS=11, /* decode arguments error */
RPC_SYSTEMERROR=12, /* generic "other problem" */
/*
* callrpc & clnt_create errors
*/
RPC_UNKNOWNHOST=13, /* unknown host name */
RPC_UNKNOWNPROTO=17, /* unkown protocol */
/*
* _ create errors
*/
RPC_PMAPFAILURE=14, /* the pmapper failed in its call */
RPC_PROGNOTREGISTERED=15, /* remote program is not registered */
/*
* unspecified error
*/
RPC_FAILED=16
};
#define RPCB_MULTICAST_ADDR "ff02::202"
/*
* the following errors are in general unrecoverable. The caller
* should give up rather than retry.
*/
#define IS_UNRECOVERABLE_RPC(s) (((s) == RPC_AUTHERROR) || \
((s) == RPC_CANTENCODEARGS) || \
((s) == RPC_CANTDECODERES) || \
((s) == RPC_VERSMISMATCH) || \
((s) == RPC_PROCUNAVAIL) || \
((s) == RPC_PROGUNAVAIL) || \
((s) == RPC_PROGVERSMISMATCH) || \
((s) == RPC_CANTDECODEARGS))
/*
* Error info.
@ -95,8 +73,8 @@ struct rpc_err {
int RE_errno; /* related system error */
enum auth_stat RE_why; /* why the auth error occurred */
struct {
u_int32_t low; /* lowest verion supported */
u_int32_t high; /* highest verion supported */
rpcvers_t low; /* lowest version supported */
rpcvers_t high; /* highest version supported */
} RE_vers;
struct { /* maybe meaningful if RPC_FAILED */
int32_t s1;
@ -112,7 +90,7 @@ struct rpc_err {
/*
* Client rpc handle.
* Created by individual implementations, see e.g. rpc_udp.c.
* Created by individual implementations
* Client is responsible for initializing auth, see e.g. auth_none.c.
*/
typedef struct __rpc_client {
@ -120,7 +98,7 @@ typedef struct __rpc_client {
struct clnt_ops {
/* call remote procedure */
enum clnt_stat (*cl_call) __P((struct __rpc_client *,
u_long, xdrproc_t, caddr_t, xdrproc_t,
rpcproc_t, xdrproc_t, caddr_t, xdrproc_t,
caddr_t, struct timeval));
/* abort a call */
void (*cl_abort) __P((struct __rpc_client *));
@ -134,12 +112,36 @@ typedef struct __rpc_client {
void (*cl_destroy) __P((struct __rpc_client *));
/* the ioctl() of rpc */
bool_t (*cl_control) __P((struct __rpc_client *, u_int,
void *));
char *));
} *cl_ops;
caddr_t cl_private; /* private stuff */
void *cl_private; /* private stuff */
char *cl_netid; /* network token */
char *cl_tp; /* device name */
} CLIENT;
/*
* Timers used for the pseudo-transport protocol when using datagrams
*/
struct rpc_timers {
u_short rt_srtt; /* smoothed round-trip time */
u_short rt_deviate; /* estimated deviation */
u_long rt_rtxcur; /* current (backed-off) rto */
};
/*
* Feedback values used for possible congestion and rate control
*/
#define FEEDBACK_REXMIT1 1 /* first retransmit */
#define FEEDBACK_OK 2 /* no retransmits */
/* Used to set version of portmapper used in broadcast */
#define CLCR_SET_LOWVERS 3
#define CLCR_GET_LOWVERS 4
#define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */
/*
* client side rpc interface ops
*
@ -151,19 +153,19 @@ typedef struct __rpc_client {
* enum clnt_stat
* CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout)
* CLIENT *rh;
* u_long proc;
* rpcproc_t proc;
* xdrproc_t xargs;
* caddr_t argsp;
* xdrproc_t xres;
* caddr_t resp;
* struct timeval timeout;
*/
#define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \
((*(rh)->cl_ops->cl_call)(rh, proc, xargs, (caddr_t)argsp, \
xres, (caddr_t)resp, secs))
#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \
((*(rh)->cl_ops->cl_call)(rh, proc, xargs, (caddr_t)argsp, \
xres, (caddr_t)resp, secs))
#define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \
((*(rh)->cl_ops->cl_call)(rh, proc, xargs, \
(caddr_t)(void *)argsp, xres, (caddr_t)(void *)resp, secs))
#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \
((*(rh)->cl_ops->cl_call)(rh, proc, xargs, \
(caddr_t)(void *)argsp, xres, (caddr_t)(void *)resp, secs))
/*
* void
@ -203,42 +205,30 @@ typedef struct __rpc_client {
#define clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
/*
* control operations that apply to udp, tcp and unix transports
*
* Note: options marked XXX are no-ops in this implementation of RPC.
* The are present in TI-RPC but can't be implemented here since they
* depend on the presence of STREAMS/TLI, which we don't have.
*
* control operations that apply to both udp and tcp transports
*/
#define CLSET_TIMEOUT 1 /* set timeout (timeval) */
#define CLGET_TIMEOUT 2 /* get timeout (timeval) */
#define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */
#define CLGET_FD 6 /* get connections file descriptor */
#define CLGET_SVC_ADDR 7 /* get server's address (netbuf) XXX */
#define CLSET_FD_CLOSE 8 /* close fd while clnt_destroy */
#define CLSET_FD_NCLOSE 9 /* Do not close fd while clnt_destroy */
#define CLGET_XID 10 /* Get xid */
#define CLSET_XID 11 /* Set xid */
#define CLGET_VERS 12 /* Get version number */
#define CLSET_VERS 13 /* Set version number */
#define CLGET_PROG 14 /* Get program number */
#define CLSET_PROG 15 /* Set program number */
#define CLSET_SVC_ADDR 16 /* get server's address (netbuf) XXX */
#define CLSET_PUSH_TIMOD 17 /* push timod if not already present XXX */
#define CLSET_POP_TIMOD 18 /* pop timod XXX */
#define CLSET_TIMEOUT 1 /* set timeout (timeval) */
#define CLGET_TIMEOUT 2 /* get timeout (timeval) */
#define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */
#define CLGET_FD 6 /* get connections file descriptor */
#define CLGET_SVC_ADDR 7 /* get server's address (netbuf) */
#define CLSET_FD_CLOSE 8 /* close fd while clnt_destroy */
#define CLSET_FD_NCLOSE 9 /* Do not close fd while clnt_destroy */
#define CLGET_XID 10 /* Get xid */
#define CLSET_XID 11 /* Set xid */
#define CLGET_VERS 12 /* Get version number */
#define CLSET_VERS 13 /* Set version number */
#define CLGET_PROG 14 /* Get program number */
#define CLSET_PROG 15 /* Set program number */
#define CLSET_SVC_ADDR 16 /* get server's address (netbuf) */
#define CLSET_PUSH_TIMOD 17 /* push timod if not already present */
#define CLSET_POP_TIMOD 18 /* pop timod */
/*
* udp only control operations
* Connectionless only control operations
*/
#define CLSET_RETRY_TIMEOUT 4 /* set retry timeout (timeval) */
#define CLGET_RETRY_TIMEOUT 5 /* get retry timeout (timeval) */
/*
* Operations which GSSAPI needs. (Bletch.)
*/
#define CLGET_LOCAL_ADDR 19 /* get local addr (sockaddr) */
/*
* void
* CLNT_DESTROY(rh);
@ -254,16 +244,16 @@ typedef struct __rpc_client {
* and network administration.
*/
#define RPCTEST_PROGRAM ((u_long)1)
#define RPCTEST_VERSION ((u_long)1)
#define RPCTEST_NULL_PROC ((u_long)2)
#define RPCTEST_NULL_BATCH_PROC ((u_long)3)
#define RPCTEST_PROGRAM ((rpcprog_t)1)
#define RPCTEST_VERSION ((rpcvers_t)1)
#define RPCTEST_NULL_PROC ((rpcproc_t)2)
#define RPCTEST_NULL_BATCH_PROC ((rpcproc_t)3)
/*
* By convention, procedure 0 takes null arguments and returns them
*/
#define NULLPROC ((u_long)0)
#define NULLPROC ((rpcproc_t)0)
/*
* Below are the client handle creation routines for the various
@ -271,109 +261,113 @@ typedef struct __rpc_client {
* creation failure occurs.
*/
/*
* Generic client creation routine. Supported protocols are those that
* belong to the nettype namespace (/etc/netconfig).
* CLIENT *
* clnt_create(host, prog, vers, prot);
* const char *host; -- hostname
* const rpcprog_t prog; -- program number
* const rpcvers_t vers; -- version number
* const char *prot; -- protocol
*/
__BEGIN_DECLS
extern CLIENT *clnt_create __P((const char *, const rpcprog_t, const rpcvers_t,
const char *));
/*
*
* const char *hostname; -- hostname
* const rpcprog_t prog; -- program number
* const rpcvers_t vers; -- version number
* const char *nettype; -- network type
*/
/*
* Generic client creation routine. Supported protocols are which belong
* to the nettype name space.
*/
extern CLIENT *clnt_create_vers __P((const char *, const rpcprog_t, rpcvers_t *,
const rpcvers_t, const rpcvers_t,
const char *));
/*
* const char *host; -- hostname
* const rpcprog_t prog; -- program number
* rpcvers_t *vers_out; -- servers highest available version
* const rpcvers_t vers_low; -- low version number
* const rpcvers_t vers_high; -- high version number
* const char *nettype; -- network type
*/
/*
* Generic client creation routine. It takes a netconfig structure
* instead of nettype
*/
extern CLIENT *clnt_tp_create __P((const char *, const rpcprog_t,
const rpcvers_t, const struct netconfig *));
/*
* const char *hostname; -- hostname
* const rpcprog_t prog; -- program number
* const rpcvers_t vers; -- version number
* const struct netconfig *netconf; -- network config structure
*/
/*
* Generic TLI create routine. Only provided for compatibility.
*/
extern CLIENT *clnt_tli_create __P((const int, const struct netconfig *,
const struct netbuf *, const rpcprog_t,
const rpcvers_t, const u_int, const u_int));
/*
* const register int fd; -- fd
* const struct netconfig *nconf; -- netconfig structure
* const struct netbuf *svcaddr; -- servers address
* const u_long prog; -- program number
* const u_long vers; -- version number
* const u_int sendsz; -- send size
* const u_int recvsz; -- recv size
*/
/*
* Low level clnt create routine for connectionful transports, e.g. tcp.
*/
extern CLIENT *clnt_vc_create __P((const int, const struct netbuf *,
const rpcprog_t, const rpcvers_t,
const u_int, const u_int));
/*
* const int fd; -- open file descriptor
* const struct netbuf *svcaddr; -- servers address
* const rpcprog_t prog; -- program number
* const rpcvers_t vers; -- version number
* const u_int sendsz; -- buffer recv size
* const u_int recvsz; -- buffer send size
*/
/*
* Low level clnt create routine for connectionless transports, e.g. udp.
*/
extern CLIENT *clnt_dg_create __P((const int, const struct netbuf *,
const rpcprog_t, const rpcvers_t,
const u_int, const u_int));
/*
* const int fd; -- open file descriptor
* const struct netbuf *svcaddr; -- servers address
* const rpcprog_t program; -- program number
* const rpcvers_t version; -- version number
* const u_int sendsz; -- buffer recv size
* const u_int recvsz; -- buffer send size
*/
/*
* Memory based rpc (for speed check and testing)
* CLIENT *
* clntraw_create(prog, vers)
* clnt_raw_create(prog, vers)
* u_long prog;
* u_long vers;
*/
__BEGIN_DECLS
extern CLIENT *clntraw_create __P((u_long, u_long));
__END_DECLS
extern CLIENT *clnt_raw_create __P((rpcprog_t, rpcvers_t));
/*
* Generic client creation routine. Supported protocols are "udp", "tcp"
* and "unix".
* CLIENT *
* clnt_create(host, prog, vers, prot);
* char *host; -- hostname
* u_long prog; -- program number
* u_long vers; -- version number
* char *prot; -- protocol
*/
__BEGIN_DECLS
extern CLIENT *clnt_create __P((char *, u_long, u_long, char *));
__END_DECLS
/*
* TCP based rpc
* CLIENT *
* clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
* struct sockaddr_in *raddr;
* u_long prog;
* u_long version;
* register int *sockp;
* u_int sendsz;
* u_int recvsz;
*/
__BEGIN_DECLS
extern CLIENT *clnttcp_create __P((struct sockaddr_in *,
u_long,
u_long,
int *,
u_int,
u_int));
__END_DECLS
/*
* UDP based rpc.
* CLIENT *
* clntudp_create(raddr, program, version, wait, sockp)
* struct sockaddr_in *raddr;
* u_long program;
* u_long version;
* struct timeval wait;
* int *sockp;
*
* Same as above, but you specify max packet sizes.
* CLIENT *
* clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
* struct sockaddr_in *raddr;
* u_long program;
* u_long version;
* struct timeval wait;
* int *sockp;
* u_int sendsz;
* u_int recvsz;
*/
__BEGIN_DECLS
extern CLIENT *clntudp_create __P((struct sockaddr_in *,
u_long,
u_long,
struct timeval,
int *));
extern CLIENT *clntudp_bufcreate __P((struct sockaddr_in *,
u_long,
u_long,
struct timeval,
int *,
u_int,
u_int));
__END_DECLS
/*
* AF_UNIX based rpc
* CLIENT *
* clntunix_create(raddr, prog, vers, sockp, sendsz, recvsz)
* struct sockaddr_un *raddr;
* u_long prog;
* u_long version;
* register int *sockp;
* u_int sendsz;
* u_int recvsz;
*/
__BEGIN_DECLS
extern CLIENT *clntunix_create __P((struct sockaddr_un *,
u_long,
u_long,
int *,
u_int,
u_int));
__END_DECLS
@ -381,8 +375,8 @@ __END_DECLS
* Print why creation failed
*/
__BEGIN_DECLS
extern void clnt_pcreateerror __P((char *)); /* stderr */
extern char *clnt_spcreateerror __P((char *)); /* string */
extern void clnt_pcreateerror __P((const char *)); /* stderr */
extern char *clnt_spcreateerror __P((const char *)); /* string */
__END_DECLS
/*
@ -397,8 +391,8 @@ __END_DECLS
* Print an English error message, given the client error code
*/
__BEGIN_DECLS
extern void clnt_perror __P((CLIENT *, char *)); /* stderr */
extern char *clnt_sperror __P((CLIENT *, char *)); /* string */
extern void clnt_perror __P((CLIENT *, const char *)); /* stderr */
extern char *clnt_sperror __P((CLIENT *, const char *)); /* string */
__END_DECLS
@ -410,10 +404,94 @@ struct rpc_createerr {
struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */
};
#ifdef _THREAD_SAFE
__BEGIN_DECLS
extern struct rpc_createerr *__rpc_createerr __P((void));
__END_DECLS
#define rpc_createerr (*(__rpc_createerr()))
#else
extern struct rpc_createerr rpc_createerr;
#endif /* _THREAD_SAFE */
/*
* The simplified interface:
* enum clnt_stat
* rpc_call(host, prognum, versnum, procnum, inproc, in, outproc, out, nettype)
* const char *host;
* const rpcprog_t prognum;
* const rpcvers_t versnum;
* const rpcproc_t procnum;
* const xdrproc_t inproc, outproc;
* const char *in;
* char *out;
* const char *nettype;
*/
__BEGIN_DECLS
extern enum clnt_stat rpc_call __P((const char *, const rpcprog_t,
const rpcvers_t, const rpcproc_t,
const xdrproc_t, const char *,
const xdrproc_t, char *, const char *));
__END_DECLS
#define UDPMSGSIZE 8800 /* rpc imposed limit on udp msg size */
#define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */
/*
* RPC broadcast interface
* The call is broadcasted to all locally connected nets.
*
* extern enum clnt_stat
* rpc_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp,
* eachresult, nettype)
* const rpcprog_t prog; -- program number
* const rpcvers_t vers; -- version number
* const rpcproc_t proc; -- procedure number
* const xdrproc_t xargs; -- xdr routine for args
* caddr_t argsp; -- pointer to args
* const xdrproc_t xresults; -- xdr routine for results
* caddr_t resultsp; -- pointer to results
* const resultproc_t eachresult; -- call with each result
* const char *nettype; -- Transport type
*
* For each valid response received, the procedure eachresult is called.
* Its form is:
* done = eachresult(resp, raddr, nconf)
* bool_t done;
* caddr_t resp;
* struct netbuf *raddr;
* struct netconfig *nconf;
* where resp points to the results of the call and raddr is the
* address if the responder to the broadcast. nconf is the transport
* on which the response was received.
*
* extern enum clnt_stat
* rpc_broadcast_exp(prog, vers, proc, xargs, argsp, xresults, resultsp,
* eachresult, inittime, waittime, nettype)
* const rpcprog_t prog; -- program number
* const rpcvers_t vers; -- version number
* const rpcproc_t proc; -- procedure number
* const xdrproc_t xargs; -- xdr routine for args
* caddr_t argsp; -- pointer to args
* const xdrproc_t xresults; -- xdr routine for results
* caddr_t resultsp; -- pointer to results
* const resultproc_t eachresult; -- call with each result
* const int inittime; -- how long to wait initially
* const int waittime; -- maximum time to wait
* const char *nettype; -- Transport type
*/
#endif /* !_RPC_CLNT_H */
typedef bool_t (*resultproc_t) __P((caddr_t, ...));
__BEGIN_DECLS
extern enum clnt_stat rpc_broadcast __P((const rpcprog_t, const rpcvers_t,
const rpcproc_t, const xdrproc_t,
caddr_t, const xdrproc_t, caddr_t,
const resultproc_t, const char *));
extern enum clnt_stat rpc_broadcast_exp __P((const rpcprog_t, const rpcvers_t,
const rpcproc_t, const xdrproc_t,
caddr_t, const xdrproc_t, caddr_t,
const resultproc_t, const int,
const int, const char *));
__END_DECLS
/* For backward compatibility */
#include <rpc/clnt_soc.h>
#endif /* !_RPC_CLNT_H_ */

118
include/rpc/clnt_soc.h Normal file
View File

@ -0,0 +1,118 @@
/* $NetBSD: clnt_soc.h,v 1.1 2000/06/02 22:57:55 fvdl Exp $ */
/* $FreeBSD$ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1984 - 1991 by Sun Microsystems, Inc.
*/
/*
* clnt.h - Client side remote procedure call interface.
*/
#ifndef _RPC_CLNT_SOC_H
#define _RPC_CLNT_SOC_H
/* derived from clnt_soc.h 1.3 88/12/17 SMI */
/*
* All the following declarations are only for backward compatibility
* with TS-RPC.
*/
#include <sys/cdefs.h>
#define UDPMSGSIZE 8800 /* rpc imposed limit on udp msg size */
/*
* TCP based rpc
* CLIENT *
* clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
* struct sockaddr_in *raddr;
* u_long prog;
* u_long version;
* register int *sockp;
* u_int sendsz;
* u_int recvsz;
*/
__BEGIN_DECLS
extern CLIENT *clnttcp_create __P((struct sockaddr_in *,
u_long,
u_long,
int *,
u_int,
u_int));
__END_DECLS
/*
* Raw (memory) rpc.
*/
__BEGIN_DECLS
extern CLIENT *clntraw_create __P((u_long, u_long));
__END_DECLS
/*
* UDP based rpc.
* CLIENT *
* clntudp_create(raddr, program, version, wait, sockp)
* struct sockaddr_in *raddr;
* u_long program;
* u_long version;
* struct timeval wait;
* int *sockp;
*
* Same as above, but you specify max packet sizes.
* CLIENT *
* clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
* struct sockaddr_in *raddr;
* u_long program;
* u_long version;
* struct timeval wait;
* int *sockp;
* u_int sendsz;
* u_int recvsz;
*/
__BEGIN_DECLS
extern CLIENT *clntudp_create __P((struct sockaddr_in *,
u_long,
u_long,
struct timeval,
int *));
extern CLIENT *clntudp_bufcreate __P((struct sockaddr_in *,
u_long,
u_long,
struct timeval,
int *,
u_int,
u_int));
__END_DECLS
#endif /* _RPC_CLNT_SOC_H */

83
include/rpc/clnt_stat.h Normal file
View File

@ -0,0 +1,83 @@
/* $FreeBSD$ */
/*
* Copyright (c) 1986 - 1991, 1994, 1996, 1997 by Sun Microsystems, Inc.
* All rights reserved.
*/
/*
* clnt_stat.h - Client side remote procedure call enum
*
*/
#ifndef _RPC_CLNT_STAT_H
#define _RPC_CLNT_STAT_H
#pragma ident "@(#)clnt_stat.h 1.2 97/04/28 SMI"
#ifdef __cplusplus
extern "C" {
#endif
enum clnt_stat {
RPC_SUCCESS = 0, /* call succeeded */
/*
* local errors
*/
RPC_CANTENCODEARGS = 1, /* can't encode arguments */
RPC_CANTDECODERES = 2, /* can't decode results */
RPC_CANTSEND = 3, /* failure in sending call */
RPC_CANTRECV = 4,
/* failure in receiving result */
RPC_TIMEDOUT = 5, /* call timed out */
RPC_INTR = 18, /* call interrupted */
RPC_UDERROR = 23, /* recv got uderr indication */
/*
* remote errors
*/
RPC_VERSMISMATCH = 6, /* rpc versions not compatible */
RPC_AUTHERROR = 7, /* authentication error */
RPC_PROGUNAVAIL = 8, /* program not available */
RPC_PROGVERSMISMATCH = 9, /* program version mismatched */
RPC_PROCUNAVAIL = 10, /* procedure unavailable */
RPC_CANTDECODEARGS = 11, /* decode arguments error */
RPC_SYSTEMERROR = 12, /* generic "other problem" */
/*
* rpc_call & clnt_create errors
*/
RPC_UNKNOWNHOST = 13, /* unknown host name */
RPC_UNKNOWNPROTO = 17, /* unknown protocol */
RPC_UNKNOWNADDR = 19, /* Remote address unknown */
RPC_NOBROADCAST = 21, /* Broadcasting not supported */
/*
* rpcbind errors
*/
RPC_RPCBFAILURE = 14, /* the pmapper failed in its call */
#define RPC_PMAPFAILURE RPC_RPCBFAILURE
RPC_PROGNOTREGISTERED = 15, /* remote program is not registered */
RPC_N2AXLATEFAILURE = 22,
/* Name to address translation failed */
/*
* Misc error in the TLI library
*/
RPC_TLIERROR = 20,
/*
* unspecified error
*/
RPC_FAILED = 16,
/*
* asynchronous errors
*/
RPC_INPROGRESS = 24,
RPC_STALERACHANDLE = 25,
RPC_CANTCONNECT = 26, /* couldn't make connection (cots) */
RPC_XPRTFAILED = 27, /* received discon from remote (cots) */
RPC_CANTCREATESTREAM = 28 /* can't push rpc module (cots) */
};
#ifdef __cplusplus
}
#endif
#endif /* !_RPC_CLNT_STAT_H */

View File

@ -33,6 +33,16 @@
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
*/
/*
* des_crypt.h, des library routine interface
*/
#ifndef _DES_DES_CRYPT_H
#define _DES_DES_CRYPT_H
#include <sys/cdefs.h>
#include <rpc/rpc.h>
@ -75,46 +85,22 @@
* Cipher Block Chaining mode
*/
__BEGIN_DECLS
#ifdef __STDC__
int cbc_crypt __P(( char *, char *, unsigned int, unsigned int, char *));
#else
cbc_crypt(/* key, buf, len, mode, ivec */); /*
char *key;
char *buf;
unsigned len;
unsigned mode;
char *ivec;
*/
#endif
__END_DECLS
/*
* Electronic Code Book mode
*/
#ifdef __STDC__
__BEGIN_DECLS
int ecb_crypt __P(( char *, char *, unsigned int, unsigned int ));
#else
ecb_crypt(/* key, buf, len, mode */); /*
char *key;
char *buf;
unsigned len;
unsigned mode;
*/
#endif
__END_DECLS
#ifndef _KERNEL
/*
* Set des parity for a key.
* DES parity is odd and in the low bit of each byte
*/
__BEGIN_DECLS
#ifdef __STDC__
void des_setparity __P(( char *));
#else
void
des_setparity(/* key */); /*
char *key;
*/
#endif
__END_DECLS
#endif
#endif /* _DES_DES_CRYPT_H */

64
include/rpc/nettype.h Normal file
View File

@ -0,0 +1,64 @@
/* $NetBSD: nettype.h,v 1.2 2000/07/06 03:17:19 christos Exp $ */
/* $FreeBSD$ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
*/
/*
* nettype.h, Nettype definitions.
* All for the topmost layer of rpc
*
*/
#ifndef _RPC_NETTYPE_H
#define _RPC_NETTYPE_H
#include <netconfig.h>
#define _RPC_NONE 0
#define _RPC_NETPATH 1
#define _RPC_VISIBLE 2
#define _RPC_CIRCUIT_V 3
#define _RPC_DATAGRAM_V 4
#define _RPC_CIRCUIT_N 5
#define _RPC_DATAGRAM_N 6
#define _RPC_TCP 7
#define _RPC_UDP 8
__BEGIN_DECLS
extern void *__rpc_setconf __P((const char *));
extern void __rpc_endconf __P((void *));
extern struct netconfig *__rpc_getconf __P((void *));
extern struct netconfig *__rpc_getconfip __P((const char *));
__END_DECLS
#endif /* !_RPC_NETTYPE_H */

View File

@ -1,3 +1,5 @@
/* $NetBSD: pmap_clnt.h,v 1.9 2000/06/02 22:57:55 fvdl Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -26,7 +28,7 @@
* 2550 Garcia Avenue
* Mountain View, California 94043
*
* from: @(#)pmap_clnt.h 1.11 88/02/08 SMI
* from: @(#)pmap_clnt.h 1.11 88/02/08 SMI
* from: @(#)pmap_clnt.h 2.1 88/07/29 4.0 RPCSRC
* $FreeBSD$
*/
@ -60,8 +62,8 @@
* address if the responder to the broadcast.
*/
#ifndef _RPC_PMAPCLNT_H
#define _RPC_PMAPCLNT_H
#ifndef _RPC_PMAP_CLNT_H_
#define _RPC_PMAP_CLNT_H_
#include <sys/cdefs.h>
__BEGIN_DECLS
@ -76,10 +78,9 @@ extern enum clnt_stat pmap_rmtcall __P((struct sockaddr_in *,
extern enum clnt_stat clnt_broadcast __P((u_long, u_long, u_long,
xdrproc_t, char *,
xdrproc_t, char *,
bool_t (*) __P((caddr_t,
struct sockaddr_in *))));
resultproc_t));
extern u_short pmap_getport __P((struct sockaddr_in *,
u_long, u_long, u_int));
__END_DECLS
#endif /* !_RPC_PMAPCLNT_H */
#endif /* !_RPC_PMAP_CLNT_H_ */

View File

@ -1,3 +1,5 @@
/* $NetBSD: pmap_prot.h,v 1.8 2000/06/02 22:57:55 fvdl Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -26,7 +28,7 @@
* 2550 Garcia Avenue
* Mountain View, California 94043
*
* from: @(#)pmap_prot.h 1.14 88/02/08 SMI
* from: @(#)pmap_prot.h 1.14 88/02/08 SMI
* from: @(#)pmap_prot.h 2.1 88/07/29 4.0 RPCSRC
* $FreeBSD$
*/
@ -68,8 +70,8 @@
* The service supports remote procedure calls on udp/ip or tcp/ip socket 111.
*/
#ifndef _RPC_PMAPPROT_H
#define _RPC_PMAPPROT_H
#ifndef _RPC_PMAP_PROT_H
#define _RPC_PMAP_PROT_H
#include <sys/cdefs.h>
#define PMAPPORT ((u_short)111)
@ -99,6 +101,7 @@ struct pmaplist {
__BEGIN_DECLS
extern bool_t xdr_pmap __P((XDR *, struct pmap *));
extern bool_t xdr_pmaplist __P((XDR *, struct pmaplist **));
extern bool_t xdr_pmaplist_ptr __P((XDR *, struct pmaplist *));
__END_DECLS
#endif /* !_RPC_PMAPPROT_H */
#endif /* !_RPC_PMAP_PROT_H */

View File

@ -1,3 +1,5 @@
/* $NetBSD: pmap_rmt.h,v 1.7 1998/02/11 23:01:23 lukem Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -38,8 +40,8 @@
* Copyright (C) 1986, Sun Microsystems, Inc.
*/
#ifndef _RPC_PMAPRMT_H
#define _RPC_PMAPRMT_H
#ifndef _RPC_PMAP_RMT_H
#define _RPC_PMAP_RMT_H
#include <sys/cdefs.h>
struct rmtcallargs {
@ -60,4 +62,4 @@ extern bool_t xdr_rmtcall_args __P((XDR *, struct rmtcallargs *));
extern bool_t xdr_rmtcallres __P((XDR *, struct rmtcallres *));
__END_DECLS
#endif /* !_RPC_PMAPRMT_H */
#endif /* !_RPC_PMAP_RMT_H */

58
include/rpc/raw.h Normal file
View File

@ -0,0 +1,58 @@
/* $NetBSD: raw.h,v 1.1 2000/06/02 22:57:56 fvdl Exp $ */
/* $FreeBSD$ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
*/
#ifndef _RPC_RAW_H
#define _RPC_RAW_H
/* from: @(#)raw.h 1.11 94/04/25 SMI */
/* from: @(#)raw.h 1.2 88/10/25 SMI */
#ifdef __cplusplus
extern "C" {
#endif
/*
* raw.h
*
* Raw interface
* The common memory area over which they will communicate
*/
extern char *__rpc_rawcombuf;
#ifdef __cplusplus
}
#endif
#endif /* _RPC_RAW_H */

View File

@ -1,3 +1,5 @@
/* $NetBSD: rpc.h,v 1.13 2000/06/02 22:57:56 fvdl Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -41,6 +43,7 @@
#define _RPC_RPC_H
#include <rpc/types.h> /* some typedefs */
#include <sys/socket.h>
#include <netinet/in.h>
/* external data representation interfaces */
@ -65,30 +68,40 @@
#include <rpc/svc.h> /* service manager and multiplexer */
#include <rpc/svc_auth.h> /* service side authenticator */
/*
* COMMENT OUT THE NEXT INCLUDE (or add to the #ifndef) IF RUNNING ON
* A VERSION OF UNIX THAT USES SUN'S NFS SOURCE. These systems will
* already have the structures defined by <rpc/netdb.h> included in <netdb.h>.
*/
/* routines for parsing /etc/rpc */
/* Portmapper client, server, and protocol headers */
#include <rpc/pmap_clnt.h>
#include <rpc/pmap_prot.h>
struct rpcent {
char *r_name; /* name of server for this rpc program */
char **r_aliases; /* alias list */
int r_number; /* rpc program number */
};
#include <rpc/rpcb_clnt.h> /* rpcbind interface functions */
#include <rpc/rpcent.h>
__BEGIN_DECLS
extern struct rpcent *getrpcbyname __P((char *));
extern struct rpcent *getrpcbynumber __P((int));
extern struct rpcent *getrpcent __P((void));
extern int getrpcport __P((char *host, int prognum, int versnum, int proto));
extern void setrpcent __P((int));
extern void endrpcent __P((void));
extern int bindresvport __P((int, struct sockaddr_in *));
extern int bindresvport_sa __P((int, struct sockaddr *));
extern int get_myaddress __P((struct sockaddr_in *));
extern int bindresvport __P((int, struct sockaddr_in *));
extern int registerrpc __P((int, int, int, char *(*) __P((char [UDPMSGSIZE])),
xdrproc_t, xdrproc_t));
extern int callrpc __P((char *, int, int, int, xdrproc_t, char *,
xdrproc_t , char *));
extern int getrpcport __P((char *, int, int, int));
char *taddr2uaddr __P((const struct netconfig *, const struct netbuf *));
struct netbuf *uaddr2taddr __P((const struct netconfig *, const char *));
struct sockaddr;
extern int bindresvport_sa __P((int, struct sockaddr *));
__END_DECLS
/*
* The following are not exported interfaces, they are for internal library
* and rpcbind use only. Do not use, they may change without notice.
*/
__BEGIN_DECLS
int __rpc_nconf2fd __P((const struct netconfig *));
int __rpc_nconf2sockinfo __P((const struct netconfig *,
struct __rpc_sockinfo *));
int __rpc_fd2sockinfo __P((int, struct __rpc_sockinfo *));
u_int __rpc_get_t_size __P((int, int, int));
__END_DECLS
#endif /* !_RPC_RPC_H */

View File

@ -1,3 +1,6 @@
/* $NetBSD: rpc_com.h,v 1.3 2000/12/10 04:10:08 christos Exp $ */
/* $FreeBSD$ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -39,17 +42,10 @@
#ifndef _RPC_RPCCOM_H
#define _RPC_RPCCOM_H
/* From: #pragma ident "@(#)rpc_com.h 1.11 93/07/05 SMI" */
#include <sys/cdefs.h>
#ifdef __cplusplus
extern "C" {
#endif
/* #pragma ident "@(#)rpc_com.h 1.11 93/07/05 SMI" */
/*
* File descriptor to be used on xxx_create calls to get default descriptor
*/
#define RPC_ANYSOCK -1
#define RPC_ANYFD RPC_ANYSOCK
/*
* The max size of the transport, if the size cannot be determined
* by other means.
@ -57,22 +53,31 @@ extern "C" {
#define RPC_MAXDATASIZE 9000
#define RPC_MAXADDRSIZE 1024
#if defined(__STDC__) || defined(__cplusplus)
extern u_int __rpc_get_t_size (int, long);
extern u_int __rpc_get_a_size (long);
extern int __rpc_dtbsize (void);
extern int _rpc_dtablesize (void);
extern int _rpc_get_default_domain(char **);
#else
extern u_int __rpc_get_t_size ();
extern u_int __rpc_get_a_size ();
extern int __rpc_dtbsize ();
extern int _rpc_dtablesize ();
extern int _rpc_get_default_domain();
#endif
#define __RPC_GETXID(now) ((u_int32_t)getpid() ^ (u_int32_t)(now)->tv_sec ^ \
(u_int32_t)(now)->tv_usec)
#ifdef __cplusplus
}
#endif
__BEGIN_DECLS
extern u_int __rpc_get_a_size __P((int));
extern int __rpc_dtbsize __P((void));
extern struct netconfig * __rpcgettp __P((int));
extern int __rpc_get_default_domain __P((char **));
char *__rpc_taddr2uaddr_af __P((int, const struct netbuf *));
struct netbuf *__rpc_uaddr2taddr_af __P((int, const char *));
int __rpc_fixup_addr __P((struct netbuf *, const struct netbuf *));
int __rpc_sockinfo2netid __P((struct __rpc_sockinfo *, const char **));
int __rpc_seman2socktype __P((int));
int __rpc_socktype2seman __P((int));
void *rpc_nullproc __P((CLIENT *));
int __rpc_sockisbound __P((int));
struct netbuf *__rpcb_findaddr __P((rpcprog_t, rpcvers_t,
const struct netconfig *,
const char *, CLIENT **));
bool_t __rpc_control __P((int,void *));
char *_get_next_token __P((char *, int));
__END_DECLS
#endif /* _RPC_RPCCOM_H */

View File

@ -1,3 +1,5 @@
/* $NetBSD: rpc_msg.h,v 1.11 2000/06/02 22:57:56 fvdl Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -38,10 +40,10 @@
* Copyright (C) 1984, Sun Microsystems, Inc.
*/
#ifndef _RPC_RPCMSG_H
#define _RPC_RPCMSG_H
#ifndef _RPC_RPC_MSG_H
#define _RPC_RPC_MSG_H
#define RPC_MSG_VERSION ((u_long) 2)
#define RPC_MSG_VERSION ((u_int32_t) 2)
#define RPC_SERVICE_PORT ((u_short) 2048)
/*
@ -88,8 +90,8 @@ struct accepted_reply {
enum accept_stat ar_stat;
union {
struct {
u_int32_t low;
u_int32_t high;
rpcvers_t low;
rpcvers_t high;
} AR_versions;
struct {
caddr_t where;
@ -108,8 +110,8 @@ struct rejected_reply {
enum reject_stat rj_stat;
union {
struct {
u_int32_t low;
u_int32_t high;
rpcvers_t low;
rpcvers_t high;
} RJ_versions;
enum auth_stat RJ_why; /* why authentication did not work */
} ru;
@ -134,10 +136,10 @@ struct reply_body {
* Body of an rpc request call.
*/
struct call_body {
u_int32_t cb_rpcvers; /* must be equal to two */
u_int32_t cb_prog;
u_int32_t cb_vers;
u_int32_t cb_proc;
rpcvers_t cb_rpcvers; /* must be equal to two */
rpcprog_t cb_prog;
rpcvers_t cb_vers;
rpcproc_t cb_proc;
struct opaque_auth cb_cred;
struct opaque_auth cb_verf; /* protocol specific - provided by client */
};
@ -183,14 +185,30 @@ extern bool_t xdr_callhdr __P((XDR *, struct rpc_msg *));
*/
extern bool_t xdr_replymsg __P((XDR *, struct rpc_msg *));
/*
* XDR routine to handle a accepted rpc reply.
* xdr_accepted_reply(xdrs, rej)
* XDR *xdrs;
* struct accepted_reply *rej;
*/
extern bool_t xdr_accepted_reply __P((XDR *, struct accepted_reply *));
/*
* XDR routine to handle a rejected rpc reply.
* xdr_rejected_reply(xdrs, rej)
* XDR *xdrs;
* struct rejected_reply *rej;
*/
extern bool_t xdr_rejected_reply __P((XDR *, struct rejected_reply *));
/*
* Fills in the error part of a reply message.
* _seterr_reply(msg, error)
* struct rpc_msg *msg;
* struct rpc_err *error;
*/
struct rpc_err;
extern void _seterr_reply __P((struct rpc_msg *, struct rpc_err *));
__END_DECLS
#endif /* !_RPC_RPCMSG_H */
#endif /* !_RPC_RPC_MSG_H */

85
include/rpc/rpcb_clnt.h Normal file
View File

@ -0,0 +1,85 @@
/* $NetBSD: rpcb_clnt.h,v 1.1 2000/06/02 22:57:56 fvdl Exp $ */
/* $FreeBSD$ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
*/
/*
* rpcb_clnt.h
* Supplies C routines to get to rpcbid services.
*
*/
/*
* Usage:
* success = rpcb_set(program, version, nconf, address);
* success = rpcb_unset(program, version, nconf);
* success = rpcb_getaddr(program, version, nconf, host);
* head = rpcb_getmaps(nconf, host);
* clnt_stat = rpcb_rmtcall(nconf, host, program, version, procedure,
* xdrargs, argsp, xdrres, resp, tout, addr_ptr)
* success = rpcb_gettime(host, timep)
* uaddr = rpcb_taddr2uaddr(nconf, taddr);
* taddr = rpcb_uaddr2uaddr(nconf, uaddr);
*/
#ifndef _RPC_RPCB_CLNT_H
#define _RPC_RPCB_CLNT_H
/* #pragma ident "@(#)rpcb_clnt.h 1.13 94/04/25 SMI" */
/* rpcb_clnt.h 1.3 88/12/05 SMI */
#include <rpc/types.h>
#include <rpc/rpcb_prot.h>
__BEGIN_DECLS
extern bool_t rpcb_set __P((const rpcprog_t, const rpcvers_t,
const struct netconfig *, const struct netbuf *));
extern bool_t rpcb_unset __P((const rpcprog_t, const rpcvers_t,
const struct netconfig *));
extern rpcblist *rpcb_getmaps __P((const struct netconfig *, const char *));
extern enum clnt_stat rpcb_rmtcall __P((const struct netconfig *,
const char *, const rpcprog_t,
const rpcvers_t, const rpcproc_t,
const xdrproc_t, const caddr_t,
const xdrproc_t, const caddr_t,
const struct timeval,
const struct netbuf *));
extern bool_t rpcb_getaddr __P((const rpcprog_t, const rpcvers_t,
const struct netconfig *, struct netbuf *,
const char *));
extern bool_t rpcb_gettime __P((const char *, time_t *));
extern char *rpcb_taddr2uaddr __P((struct netconfig *, struct netbuf *));
extern struct netbuf *rpcb_uaddr2taddr __P((struct netconfig *, char *));
__END_DECLS
#endif /* !_RPC_RPCB_CLNT_H */

554
include/rpc/rpcb_prot.x Normal file
View File

@ -0,0 +1,554 @@
%/*
% * $FreeBSD$
% *
% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
% * unrestricted use provided that this legend is included on all tape
% * media and as a part of the software program in whole or part. Users
% * may copy or modify Sun RPC without charge, but are not authorized
% * to license or distribute it to anyone else except as part of a product or
% * program developed by the user.
% *
% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
% *
% * Sun RPC is provided with no support and without any obligation on the
% * part of Sun Microsystems, Inc. to assist in its use, correction,
% * modification or enhancement.
% *
% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
% * OR ANY PART THEREOF.
% *
% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
% * or profits or other special, indirect and consequential damages, even if
% * Sun has been advised of the possibility of such damages.
% *
% * Sun Microsystems, Inc.
% * 2550 Garcia Avenue
% * Mountain View, California 94043
% */
%/*
% * Copyright (c) 1988 by Sun Microsystems, Inc.
% */
%/* from rpcb_prot.x */
#ifdef RPC_HDR
%
%/* #pragma ident "@(#)rpcb_prot.x 1.5 94/04/29 SMI" */
%
%#ifndef _KERNEL
%
#endif
/*
* rpcb_prot.x
* rpcbind protocol, versions 3 and 4, in RPC Language
*/
%
%/*
% * The following procedures are supported by the protocol in version 3:
% *
% * RPCBPROC_NULL() returns ()
% * takes nothing, returns nothing
% *
% * RPCBPROC_SET(rpcb) returns (bool_t)
% * TRUE is success, FALSE is failure. Registers the tuple
% * [prog, vers, address, owner, netid].
% * Finds out owner and netid information on its own.
% *
% * RPCBPROC_UNSET(rpcb) returns (bool_t)
% * TRUE is success, FALSE is failure. Un-registers tuple
% * [prog, vers, netid]. addresses is ignored.
% * If netid is NULL, unregister all.
% *
% * RPCBPROC_GETADDR(rpcb) returns (string).
% * 0 is failure. Otherwise returns the universal address where the
% * triple [prog, vers, netid] is registered. Ignore address and owner.
% *
% * RPCBPROC_DUMP() RETURNS (rpcblist_ptr)
% * used to dump the entire rpcbind maps
% *
% * RPCBPROC_CALLIT(rpcb_rmtcallargs)
% * RETURNS (rpcb_rmtcallres);
% * Calls the procedure on the remote machine. If it is not registered,
% * this procedure is quiet; i.e. it does not return error information!!!
% * This routine only passes null authentication parameters.
% * It has no interface to xdr routines for RPCBPROC_CALLIT.
% *
% * RPCBPROC_GETTIME() returns (int).
% * Gets the remote machines time
% *
% * RPCBPROC_UADDR2TADDR(strint) RETURNS (struct netbuf)
% * Returns the netbuf address from universal address.
% *
% * RPCBPROC_TADDR2UADDR(struct netbuf) RETURNS (string)
% * Returns the universal address from netbuf address.
% *
% * END OF RPCBIND VERSION 3 PROCEDURES
% */
%/*
% * Except for RPCBPROC_CALLIT, the procedures above are carried over to
% * rpcbind version 4. Those below are added or modified for version 4.
% * NOTE: RPCBPROC_BCAST HAS THE SAME FUNCTIONALITY AND PROCEDURE NUMBER
% * AS RPCBPROC_CALLIT.
% *
% * RPCBPROC_BCAST(rpcb_rmtcallargs)
% * RETURNS (rpcb_rmtcallres);
% * Calls the procedure on the remote machine. If it is not registered,
% * this procedure IS quiet; i.e. it DOES NOT return error information!!!
% * This routine should be used for broadcasting and nothing else.
% *
% * RPCBPROC_GETVERSADDR(rpcb) returns (string).
% * 0 is failure. Otherwise returns the universal address where the
% * triple [prog, vers, netid] is registered. Ignore address and owner.
% * Same as RPCBPROC_GETADDR except that if the given version number
% * is not available, the address is not returned.
% *
% * RPCBPROC_INDIRECT(rpcb_rmtcallargs)
% * RETURNS (rpcb_rmtcallres);
% * Calls the procedure on the remote machine. If it is not registered,
% * this procedure is NOT quiet; i.e. it DOES return error information!!!
% * as any normal application would expect.
% *
% * RPCBPROC_GETADDRLIST(rpcb) returns (rpcb_entry_list_ptr).
% * Same as RPCBPROC_GETADDR except that it returns a list of all the
% * addresses registered for the combination (prog, vers) (for all
% * transports).
% *
% * RPCBPROC_GETSTAT(void) returns (rpcb_stat_byvers)
% * Returns the statistics about the kind of requests received by rpcbind.
% */
%
%/*
% * A mapping of (program, version, network ID) to address
% */
struct rpcb {
rpcprog_t r_prog; /* program number */
rpcvers_t r_vers; /* version number */
string r_netid<>; /* network id */
string r_addr<>; /* universal address */
string r_owner<>; /* owner of this service */
};
#ifdef RPC_HDR
%
%typedef rpcb RPCB;
%
#endif
%
%/*
% * A list of mappings
% *
% * Below are two definitions for the rpcblist structure. This is done because
% * xdr_rpcblist() is specified to take a struct rpcblist **, rather than a
% * struct rpcblist * that rpcgen would produce. One version of the rpcblist
% * structure (actually called rp__list) is used with rpcgen, and the other is
% * defined only in the header file for compatibility with the specified
% * interface.
% */
struct rp__list {
rpcb rpcb_map;
struct rp__list *rpcb_next;
};
typedef rp__list *rpcblist_ptr; /* results of RPCBPROC_DUMP */
#ifdef RPC_HDR
%
%typedef struct rp__list rpcblist;
%typedef struct rp__list RPCBLIST;
%
%#ifndef __cplusplus
%struct rpcblist {
% RPCB rpcb_map;
% struct rpcblist *rpcb_next;
%};
%#endif
%
%#ifdef __cplusplus
%extern "C" {
%#endif
%extern bool_t xdr_rpcblist(XDR *, rpcblist**);
%#ifdef __cplusplus
%}
%#endif
%
#endif
%
%/*
% * Arguments of remote calls
% */
struct rpcb_rmtcallargs {
rpcprog_t prog; /* program number */
rpcvers_t vers; /* version number */
rpcproc_t proc; /* procedure number */
opaque args<>; /* argument */
};
#ifdef RPC_HDR
%
%/*
% * Client-side only representation of rpcb_rmtcallargs structure.
% *
% * The routine that XDRs the rpcb_rmtcallargs structure must deal with the
% * opaque arguments in the "args" structure. xdr_rpcb_rmtcallargs() needs to
% * be passed the XDR routine that knows the args' structure. This routine
% * doesn't need to go over-the-wire (and it wouldn't make sense anyway) since
% * the application being called already knows the args structure. So we use a
% * different "XDR" structure on the client side, r_rpcb_rmtcallargs, which
% * includes the args' XDR routine.
% */
%struct r_rpcb_rmtcallargs {
% rpcprog_t prog;
% rpcvers_t vers;
% rpcproc_t proc;
% struct {
% u_int args_len;
% char *args_val;
% } args;
% xdrproc_t xdr_args; /* encodes args */
%};
%
#endif /* def RPC_HDR */
%
%/*
% * Results of the remote call
% */
struct rpcb_rmtcallres {
string addr<>; /* remote universal address */
opaque results<>; /* result */
};
#ifdef RPC_HDR
%
%/*
% * Client-side only representation of rpcb_rmtcallres structure.
% */
%struct r_rpcb_rmtcallres {
% char *addr;
% struct {
% u_int32_t results_len;
% char *results_val;
% } results;
% xdrproc_t xdr_res; /* decodes results */
%};
#endif RPC_HDR
%
%/*
% * rpcb_entry contains a merged address of a service on a particular
% * transport, plus associated netconfig information. A list of rpcb_entrys
% * is returned by RPCBPROC_GETADDRLIST. See netconfig.h for values used
% * in r_nc_* fields.
% */
struct rpcb_entry {
string r_maddr<>; /* merged address of service */
string r_nc_netid<>; /* netid field */
unsigned int r_nc_semantics; /* semantics of transport */
string r_nc_protofmly<>; /* protocol family */
string r_nc_proto<>; /* protocol name */
};
%
%/*
% * A list of addresses supported by a service.
% */
struct rpcb_entry_list {
rpcb_entry rpcb_entry_map;
struct rpcb_entry_list *rpcb_entry_next;
};
typedef rpcb_entry_list *rpcb_entry_list_ptr;
%
%/*
% * rpcbind statistics
% */
%
const rpcb_highproc_2 = RPCBPROC_CALLIT;
const rpcb_highproc_3 = RPCBPROC_TADDR2UADDR;
const rpcb_highproc_4 = RPCBPROC_GETSTAT;
const RPCBSTAT_HIGHPROC = 13; /* # of procs in rpcbind V4 plus one */
const RPCBVERS_STAT = 3; /* provide only for rpcbind V2, V3 and V4 */
const RPCBVERS_4_STAT = 2;
const RPCBVERS_3_STAT = 1;
const RPCBVERS_2_STAT = 0;
%
%/* Link list of all the stats about getport and getaddr */
struct rpcbs_addrlist {
rpcprog_t prog;
rpcvers_t vers;
int success;
int failure;
string netid<>;
struct rpcbs_addrlist *next;
};
%
%/* Link list of all the stats about rmtcall */
struct rpcbs_rmtcalllist {
rpcprog_t prog;
rpcvers_t vers;
rpcproc_t proc;
int success;
int failure;
int indirect; /* whether callit or indirect */
string netid<>;
struct rpcbs_rmtcalllist *next;
};
typedef int rpcbs_proc[RPCBSTAT_HIGHPROC];
typedef rpcbs_addrlist *rpcbs_addrlist_ptr;
typedef rpcbs_rmtcalllist *rpcbs_rmtcalllist_ptr;
struct rpcb_stat {
rpcbs_proc info;
int setinfo;
int unsetinfo;
rpcbs_addrlist_ptr addrinfo;
rpcbs_rmtcalllist_ptr rmtinfo;
};
%
%/*
% * One rpcb_stat structure is returned for each version of rpcbind
% * being monitored.
% */
typedef rpcb_stat rpcb_stat_byvers[RPCBVERS_STAT];
#ifdef RPC_HDR
%
%/*
% * We don't define netbuf in RPCL, since it would contain structure member
% * names that would conflict with the definition of struct netbuf in
% * <tiuser.h>. Instead we merely declare the XDR routine xdr_netbuf() here,
% * and implement it ourselves in rpc/rpcb_prot.c.
% */
%#ifdef __cplusplus
%extern "C" bool_t xdr_netbuf(XDR *, struct netbuf *);
%
%#else __STDC__
%extern bool_t xdr_netbuf(XDR *, struct netbuf *);
%
%#endif
#endif /* def RPC_HDR */
/*
* rpcbind procedures
*/
program RPCBPROG {
version RPCBVERS {
bool
RPCBPROC_SET(rpcb) = 1;
bool
RPCBPROC_UNSET(rpcb) = 2;
string
RPCBPROC_GETADDR(rpcb) = 3;
rpcblist_ptr
RPCBPROC_DUMP(void) = 4;
rpcb_rmtcallres
RPCBPROC_CALLIT(rpcb_rmtcallargs) = 5;
unsigned int
RPCBPROC_GETTIME(void) = 6;
struct netbuf
RPCBPROC_UADDR2TADDR(string) = 7;
string
RPCBPROC_TADDR2UADDR(struct netbuf) = 8;
} = 3;
version RPCBVERS4 {
bool
RPCBPROC_SET(rpcb) = 1;
bool
RPCBPROC_UNSET(rpcb) = 2;
string
RPCBPROC_GETADDR(rpcb) = 3;
rpcblist_ptr
RPCBPROC_DUMP(void) = 4;
/*
* NOTE: RPCBPROC_BCAST has the same functionality as CALLIT;
* the new name is intended to indicate that this
* procedure should be used for broadcast RPC, and
* RPCBPROC_INDIRECT should be used for indirect calls.
*/
rpcb_rmtcallres
RPCBPROC_BCAST(rpcb_rmtcallargs) = RPCBPROC_CALLIT;
unsigned int
RPCBPROC_GETTIME(void) = 6;
struct netbuf
RPCBPROC_UADDR2TADDR(string) = 7;
string
RPCBPROC_TADDR2UADDR(struct netbuf) = 8;
string
RPCBPROC_GETVERSADDR(rpcb) = 9;
rpcb_rmtcallres
RPCBPROC_INDIRECT(rpcb_rmtcallargs) = 10;
rpcb_entry_list_ptr
RPCBPROC_GETADDRLIST(rpcb) = 11;
rpcb_stat_byvers
RPCBPROC_GETSTAT(void) = 12;
} = 4;
} = 100000;
#ifdef RPC_HDR
%
%#define RPCBVERS_3 RPCBVERS
%#define RPCBVERS_4 RPCBVERS4
%
%#define _PATH_RPCBINDSOCK "/var/run/rpcbind.sock"
%
%#else /* ndef _KERNEL */
%#ifdef __cplusplus
%extern "C" {
%#endif
%
%/*
% * A mapping of (program, version, network ID) to address
% */
%struct rpcb {
% rpcprog_t r_prog; /* program number */
% rpcvers_t r_vers; /* version number */
% char *r_netid; /* network id */
% char *r_addr; /* universal address */
% char *r_owner; /* owner of the mapping */
%};
%typedef struct rpcb RPCB;
%
%/*
% * A list of mappings
% */
%struct rpcblist {
% RPCB rpcb_map;
% struct rpcblist *rpcb_next;
%};
%typedef struct rpcblist RPCBLIST;
%typedef struct rpcblist *rpcblist_ptr;
%
%/*
% * Remote calls arguments
% */
%struct rpcb_rmtcallargs {
% rpcprog_t prog; /* program number */
% rpcvers_t vers; /* version number */
% rpcproc_t proc; /* procedure number */
% u_int32_t arglen; /* arg len */
% caddr_t args_ptr; /* argument */
% xdrproc_t xdr_args; /* XDR routine for argument */
%};
%typedef struct rpcb_rmtcallargs rpcb_rmtcallargs;
%
%/*
% * Remote calls results
% */
%struct rpcb_rmtcallres {
% char *addr_ptr; /* remote universal address */
% u_int32_t resultslen; /* results length */
% caddr_t results_ptr; /* results */
% xdrproc_t xdr_results; /* XDR routine for result */
%};
%typedef struct rpcb_rmtcallres rpcb_rmtcallres;
%
%struct rpcb_entry {
% char *r_maddr;
% char *r_nc_netid;
% unsigned int r_nc_semantics;
% char *r_nc_protofmly;
% char *r_nc_proto;
%};
%typedef struct rpcb_entry rpcb_entry;
%
%/*
% * A list of addresses supported by a service.
% */
%
%struct rpcb_entry_list {
% rpcb_entry rpcb_entry_map;
% struct rpcb_entry_list *rpcb_entry_next;
%};
%typedef struct rpcb_entry_list rpcb_entry_list;
%
%typedef rpcb_entry_list *rpcb_entry_list_ptr;
%
%/*
% * rpcbind statistics
% */
%
%#define rpcb_highproc_2 RPCBPROC_CALLIT
%#define rpcb_highproc_3 RPCBPROC_TADDR2UADDR
%#define rpcb_highproc_4 RPCBPROC_GETSTAT
%#define RPCBSTAT_HIGHPROC 13
%#define RPCBVERS_STAT 3
%#define RPCBVERS_4_STAT 2
%#define RPCBVERS_3_STAT 1
%#define RPCBVERS_2_STAT 0
%
%/* Link list of all the stats about getport and getaddr */
%
%struct rpcbs_addrlist {
% rpcprog_t prog;
% rpcvers_t vers;
% int success;
% int failure;
% char *netid;
% struct rpcbs_addrlist *next;
%};
%typedef struct rpcbs_addrlist rpcbs_addrlist;
%
%/* Link list of all the stats about rmtcall */
%
%struct rpcbs_rmtcalllist {
% rpcprog_t prog;
% rpcvers_t vers;
% rpcproc_t proc;
% int success;
% int failure;
% int indirect;
% char *netid;
% struct rpcbs_rmtcalllist *next;
%};
%typedef struct rpcbs_rmtcalllist rpcbs_rmtcalllist;
%
%typedef int rpcbs_proc[RPCBSTAT_HIGHPROC];
%
%typedef rpcbs_addrlist *rpcbs_addrlist_ptr;
%
%typedef rpcbs_rmtcalllist *rpcbs_rmtcalllist_ptr;
%
%struct rpcb_stat {
% rpcbs_proc info;
% int setinfo;
% int unsetinfo;
% rpcbs_addrlist_ptr addrinfo;
% rpcbs_rmtcalllist_ptr rmtinfo;
%};
%typedef struct rpcb_stat rpcb_stat;
%
%/*
% * One rpcb_stat structure is returned for each version of rpcbind
% * being monitored.
% */
%
%typedef rpcb_stat rpcb_stat_byvers[RPCBVERS_STAT];
%
%#ifdef __cplusplus
%}
%#endif
%
%#endif /* ndef _KERNEL */
#endif /* RPC_HDR */

69
include/rpc/rpcent.h Normal file
View File

@ -0,0 +1,69 @@
/* $NetBSD: rpcent.h,v 1.1 2000/06/02 22:57:56 fvdl Exp $ */
/* $FreeBSD$ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
*/
/*
* rpcent.h,
* For converting rpc program numbers to names etc.
*
*/
#ifndef _RPC_RPCENT_H
#define _RPC_RPCENT_H
/* #pragma ident "@(#)rpcent.h 1.13 94/04/25 SMI" */
/* @(#)rpcent.h 1.1 88/12/06 SMI */
struct rpcent {
char *r_name; /* name of server for this rpc program */
char **r_aliases; /* alias list */
int r_number; /* rpc program number */
};
__BEGIN_DECLS
extern struct rpcent *getrpcbyname_r __P((const char *, struct rpcent *,
char *, int));
extern struct rpcent *getrpcbynumber_r __P((int, struct rpcent *, char *, int));
extern struct rpcent *getrpcent_r __P((struct rpcent *, char *, int));
/* Old interfaces that return a pointer to a static area; MT-unsafe */
extern struct rpcent *getrpcbyname __P((char *));
extern struct rpcent *getrpcbynumber __P((int));
extern struct rpcent *getrpcent __P((void));
extern void setrpcent __P((int));
extern void endrpcent __P((void));
__END_DECLS
#endif /* !_RPC_CENT_H */

View File

@ -1,3 +1,5 @@
/* $NetBSD: svc.h,v 1.17 2000/06/02 22:57:56 fvdl Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -26,15 +28,15 @@
* 2550 Garcia Avenue
* Mountain View, California 94043
*
* from: @(#)svc.h 1.20 88/02/08 SMI
* from: @(#)svc.h 2.2 88/07/29 4.0 RPCSRC
* from: @(#)svc.h 1.35 88/12/17 SMI
* from: @(#)svc.h 1.27 94/04/25 SMI
* $FreeBSD$
*/
/*
* svc.h, Server-side remote procedure call interface.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
* Copyright (C) 1986-1993 by Sun Microsystems, Inc.
*/
#ifndef _RPC_SVC_H
@ -63,21 +65,26 @@
* parameters, struct svc_req * and SVCXPRT *, defined below.
*/
/*
* Service control requests
*/
#define SVCGET_VERSQUIET 1
#define SVCSET_VERSQUIET 2
enum xprt_stat {
XPRT_DIED,
XPRT_MOREREQS,
XPRT_IDLE
};
struct rpc_msg;
/*
* Server side transport handle
*/
typedef struct __rpc_svcxprt {
int xp_sock;
int xp_fd;
u_short xp_port; /* associated port number */
struct xp_ops {
const struct xp_ops {
/* receive incoming requests */
bool_t (*xp_recv) __P((struct __rpc_svcxprt *,
struct rpc_msg *));
@ -96,16 +103,45 @@ typedef struct __rpc_svcxprt {
void (*xp_destroy) __P((struct __rpc_svcxprt *));
} *xp_ops;
int xp_addrlen; /* length of remote address */
struct sockaddr_in xp_raddr; /* remote address */
struct sockaddr_in xp_raddr; /* remote addr. (backward ABI compat) */
/* XXX - fvdl stick this here for ABI backward compat reasons */
const struct xp_ops2 {
/* catch-all function */
bool_t (*xp_control) __P((struct __rpc_svcxprt *, const u_int,
void *));
} *xp_ops2;
char *xp_tp; /* transport provider device name */
char *xp_netid; /* network token */
struct netbuf xp_ltaddr; /* local transport address */
struct netbuf xp_rtaddr; /* remote transport address */
struct opaque_auth xp_verf; /* raw response verifier */
caddr_t xp_p1; /* private */
caddr_t xp_p2; /* private */
void *xp_p1; /* private: for use by svc ops */
void *xp_p2; /* private: for use by svc ops */
void *xp_p3; /* private: for use by svc lib */
int xp_type; /* transport type */
} SVCXPRT;
/*
* Service request
*/
struct svc_req {
u_int32_t rq_prog; /* service program number */
u_int32_t rq_vers; /* service protocol version */
u_int32_t rq_proc; /* the desired procedure */
struct opaque_auth rq_cred; /* raw creds from the wire */
void *rq_clntcred; /* read only cooked cred */
SVCXPRT *rq_xprt; /* associated transport */
};
/*
* Approved way of getting address of caller
*/
#define svc_getcaller(x) (&(x)->xp_raddr)
#define svc_getrpccaller(x) (&(x)->xp_rtaddr)
/*
* FreeBSD-only definition to get the creds of the caller (AF_LOCAL).
*/
#define __svc_getcallercreds(x) ((struct cmsgcred *)(x)->xp_p2)
/*
* Operations defined on an SVCXPRT handle
@ -145,44 +181,36 @@ typedef struct __rpc_svcxprt {
#define svc_destroy(xprt) \
(*(xprt)->xp_ops->xp_destroy)(xprt)
/*
* Service request
*/
struct svc_req {
u_int32_t rq_prog; /* service program number */
u_int32_t rq_vers; /* service protocol version */
u_int32_t rq_proc; /* the desired procedure */
struct opaque_auth rq_cred; /* raw creds from the wire */
caddr_t rq_clntcred; /* read only cooked cred */
SVCXPRT *rq_xprt; /* associated transport */
};
#define SVC_CONTROL(xprt, rq, in) \
(*(xprt)->xp_ops2->xp_control)((xprt), (rq), (in))
/*
* Service registration
*
* svc_register(xprt, prog, vers, dispatch, protocol)
* SVCXPRT *xprt;
* u_long prog;
* u_long vers;
* void (*dispatch)();
* int protocol; (like TCP or UDP, zero means do not register)
* svc_reg(xprt, prog, vers, dispatch, nconf)
* const SVCXPRT *xprt;
* const rpcprog_t prog;
* const rpcvers_t vers;
* const void (*dispatch)();
* const struct netconfig *nconf;
*/
__BEGIN_DECLS
extern bool_t svc_register __P((SVCXPRT *, u_long, u_long,
void (*) __P((struct svc_req *, SVCXPRT *)), int));
extern bool_t svc_reg __P((SVCXPRT *, const rpcprog_t, const rpcvers_t,
void (*) __P((struct svc_req *, SVCXPRT *)),
const struct netconfig *));
__END_DECLS
/*
* Service un-registration
*
* svc_unregister(prog, vers)
* u_long prog;
* u_long vers;
* svc_unreg(prog, vers)
* const rpcprog_t prog;
* const rpcvers_t vers;
*/
__BEGIN_DECLS
extern void svc_unregister __P((u_long, u_long));
extern void svc_unreg __P((const rpcprog_t, const rpcvers_t));
__END_DECLS
/*
@ -206,8 +234,6 @@ extern void xprt_unregister __P((SVCXPRT *));
__END_DECLS
/*
* When the service routine is called, it must first check to see if it
* knows about the procedure; if not, it should call svcerr_noproc
@ -239,10 +265,13 @@ extern bool_t svc_sendreply __P((SVCXPRT *, xdrproc_t, char *));
extern void svcerr_decode __P((SVCXPRT *));
extern void svcerr_weakauth __P((SVCXPRT *));
extern void svcerr_noproc __P((SVCXPRT *));
extern void svcerr_progvers __P((SVCXPRT *, u_long, u_long));
extern void svcerr_progvers __P((SVCXPRT *, rpcvers_t, rpcvers_t));
extern void svcerr_auth __P((SVCXPRT *, enum auth_stat));
extern void svcerr_noprog __P((SVCXPRT *));
extern void svcerr_systemerr __P((SVCXPRT *));
extern int rpc_reg __P((rpcprog_t, rpcvers_t, rpcproc_t,
char *(*) __P((char *)), xdrproc_t, xdrproc_t,
char *));
__END_DECLS
/*
@ -261,64 +290,130 @@ __END_DECLS
* dynamic; must be inspected before each call to select
*/
extern int svc_maxfd;
#ifdef FD_SETSIZE
extern fd_set svc_fdset;
#define svc_fds svc_fdset.fds_bits[0] /* compatibility */
#else
extern int svc_fds;
#endif /* def FD_SETSIZE */
#ifndef _KERNEL
/*
* a small program implemented by the svc_rpc implementation itself;
* also see clnt.h for protocol numbers.
*/
extern void rpctest_service();
#endif
__BEGIN_DECLS
extern void rpctest_service __P((void));
__END_DECLS
__BEGIN_DECLS
extern void svc_getreq __P((int));
extern void svc_getreqset __P((fd_set *));
extern void svc_getreqset2 __P((fd_set *, int)); /* XXX: nonstd, undoc */
extern void svc_getreq_common __P((int));
struct pollfd;
extern void svc_getreq_poll __P((struct pollfd *, int));
extern void svc_run __P((void));
extern void svc_exit __P((void));
__END_DECLS
/*
* Socket to use on svcxxx_create call to get default socket
*/
#define RPC_ANYSOCK -1
#define RPC_ANYFD RPC_ANYSOCK
/*
* These are the existing service side transport implementations
*/
/*
* Memory based rpc for testing and timing.
*/
__BEGIN_DECLS
extern SVCXPRT *svcraw_create __P((void));
__END_DECLS
/*
* Transport independent svc_create routine.
*/
extern int svc_create __P((void (*) __P((struct svc_req *, SVCXPRT *)),
const rpcprog_t, const rpcvers_t, const char *));
/*
* void (*dispatch)(); -- dispatch routine
* const rpcprog_t prognum; -- program number
* const rpcvers_t versnum; -- version number
* const char *nettype; -- network type
*/
/*
* Udp based rpc.
* Generic server creation routine. It takes a netconfig structure
* instead of a nettype.
*/
__BEGIN_DECLS
extern SVCXPRT *svcudp_create __P((int));
extern SVCXPRT *svcudp_bufcreate __P((int, u_int, u_int));
__END_DECLS
extern SVCXPRT *svc_tp_create __P((void (*) __P((struct svc_req *, SVCXPRT *)),
const rpcprog_t, const rpcvers_t,
const struct netconfig *));
/*
* void (*dispatch)(); -- dispatch routine
* const rpcprog_t prognum; -- program number
* const rpcvers_t versnum; -- version number
* const struct netconfig *nconf; -- netconfig structure
*/
/*
* Tcp based rpc.
* Generic TLI create routine
*/
extern SVCXPRT *svc_tli_create __P((const int, const struct netconfig *,
const struct t_bind *, const u_int,
const u_int));
/*
* const int fd; -- connection end point
* const struct netconfig *nconf; -- netconfig structure for network
* const struct t_bind *bindaddr; -- local bind address
* const u_int sendsz; -- max sendsize
* const u_int recvsz; -- max recvsize
*/
__BEGIN_DECLS
extern SVCXPRT *svctcp_create __P((int, u_int, u_int));
extern SVCXPRT *svcfd_create __P((int, u_int, u_int));
__END_DECLS
/*
* AF_UNIX socket based rpc.
* Connectionless and connectionful create routines
*/
__BEGIN_DECLS
extern SVCXPRT *svcunix_create __P((int, u_int, u_int, char *));
extern SVCXPRT *svcunixfd_create __P((int, u_int, u_int));
extern SVCXPRT *svc_vc_create __P((const int, const u_int, const u_int));
/*
* const int fd; -- open connection end point
* const u_int sendsize; -- max send size
* const u_int recvsize; -- max recv size
*/
extern SVCXPRT *svc_dg_create __P((const int, const u_int, const u_int));
/*
* const int fd; -- open connection
* const u_int sendsize; -- max send size
* const u_int recvsize; -- max recv size
*/
/*
* the routine takes any *open* connection
* descriptor as its first input and is used for open connections.
*/
extern SVCXPRT *svc_fd_create __P((const int, const u_int, const u_int));
/*
* const int fd; -- open connection end point
* const u_int sendsize; -- max send size
* const u_int recvsize; -- max recv size
*/
/*
* Memory based rpc (for speed check and testing)
*/
extern SVCXPRT *svc_raw_create __P((void));
/*
* svc_dg_enable_cache() enables the cache on dg transports.
*/
int svc_dg_enablecache __P((SVCXPRT *, const u_int));
__END_DECLS
/* for backward compatibility */
#include <rpc/svc_soc.h>
#endif /* !_RPC_SVC_H */

View File

@ -1,3 +1,5 @@
/* $NetBSD: svc_auth.h,v 1.8 2000/06/02 22:57:57 fvdl Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -27,7 +29,7 @@
* Mountain View, California 94043
*
* from: @(#)svc_auth.h 1.6 86/07/16 SMI
* from: @(#)svc_auth.h 2.1 88/07/29 4.0 RPCSRC
* @(#)svc_auth.h 2.1 88/07/29 4.0 RPCSRC
* $FreeBSD$
*/
@ -37,20 +39,17 @@
* Copyright (C) 1984, Sun Microsystems, Inc.
*/
#ifndef _RPC_SVCAUTH_H
#define _RPC_SVCAUTH_H
struct rpc_msg;
struct svc_req;
#ifndef _RPC_SVC_AUTH_H
#define _RPC_SVC_AUTH_H
/*
* Server side authenticator
*/
__BEGIN_DECLS
extern enum auth_stat _authenticate __P((struct svc_req *, struct rpc_msg *));
extern int svc_auth_reg __P((int, enum auth_stat (*)(struct svc_req *,
struct rpc_msg *)));
extern enum auth_stat _svcauth_des __P((struct svc_req *, struct rpc_msg *));
extern int svc_auth_reg __P((int, enum auth_stat (*) __P((struct svc_req *,
struct rpc_msg *))));
__END_DECLS
#endif /* !_RPC_SVCAUTH_H */
#endif /* !_RPC_SVC_AUTH_H */

51
include/rpc/svc_dg.h Normal file
View File

@ -0,0 +1,51 @@
/* $NetBSD: svc_dg.h,v 1.1 2000/06/02 23:11:16 fvdl Exp $ */
/* $FreeBSD$ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* XXX - this file exists only so that the rpcbind code can pull it in.
* This should go away. It should only be include by svc_dg.c and
* rpcb_svc_com.c in the rpcbind code.
*/
/*
* kept in xprt->xp_p2
*/
struct svc_dg_data {
/* XXX: optbuf should be the first field, used by ti_opts.c code */
size_t su_iosz; /* size of send.recv buffer */
u_int32_t su_xid; /* transaction id */
XDR su_xdrs; /* XDR handle */
char su_verfbody[MAX_AUTH_BYTES]; /* verifier body */
void *su_cache; /* cached data, NULL if none */
};
#define __rpcb_get_dg_xidp(x) (&((struct svc_dg_data *)(x)->xp_p2)->su_xid)

116
include/rpc/svc_soc.h Normal file
View File

@ -0,0 +1,116 @@
/* $NetBSD: svc_soc.h,v 1.1 2000/06/02 22:57:57 fvdl Exp $ */
/* $FreeBSD$ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
*/
/*
* svc.h, Server-side remote procedure call interface.
*/
#ifndef _RPC_SVC_SOC_H
#define _RPC_SVC_SOC_H
#include <sys/cdefs.h>
/* #pragma ident "@(#)svc_soc.h 1.11 94/04/25 SMI" */
/* svc_soc.h 1.8 89/05/01 SMI */
/*
* All the following declarations are only for backward compatibility
* with TS-RPC
*/
/*
* Approved way of getting address of caller
*/
#define svc_getcaller(x) (&(x)->xp_raddr)
/*
* Service registration
*
* svc_register(xprt, prog, vers, dispatch, protocol)
* SVCXPRT *xprt;
* u_long prog;
* u_long vers;
* void (*dispatch)();
* int protocol; like TCP or UDP, zero means do not register
*/
__BEGIN_DECLS
extern bool_t svc_register __P((SVCXPRT *, u_long, u_long,
void (*) __P((struct svc_req *, SVCXPRT *)), int));
__END_DECLS
/*
* Service un-registration
*
* svc_unregister(prog, vers)
* u_long prog;
* u_long vers;
*/
__BEGIN_DECLS
extern void svc_unregister __P((u_long, u_long));
__END_DECLS
/*
* Memory based rpc for testing and timing.
*/
__BEGIN_DECLS
extern SVCXPRT *svcraw_create __P((void));
__END_DECLS
/*
* Udp based rpc.
*/
__BEGIN_DECLS
extern SVCXPRT *svcudp_create __P((int));
extern SVCXPRT *svcudp_bufcreate __P((int, u_int, u_int));
extern int svcudp_enablecache __P((SVCXPRT *, u_long));
__END_DECLS
/*
* Tcp based rpc.
*/
__BEGIN_DECLS
extern SVCXPRT *svctcp_create __P((int, u_int, u_int));
__END_DECLS
/*
* Fd based rpc.
*/
__BEGIN_DECLS
extern SVCXPRT *svcfd_create __P((int, u_int, u_int));
__END_DECLS
#endif /* !_RPC_SVC_SOC_H */

View File

@ -1,3 +1,5 @@
/* $NetBSD: types.h,v 1.13 2000/06/13 01:02:44 thorpej Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -37,8 +39,18 @@
#ifndef _RPC_TYPES_H
#define _RPC_TYPES_H
#define bool_t int32_t
#define enum_t int32_t
#include <sys/types.h>
typedef int32_t bool_t;
typedef int32_t enum_t;
typedef u_int32_t rpcprog_t;
typedef u_int32_t rpcvers_t;
typedef u_int32_t rpcproc_t;
typedef u_int32_t rpcprot_t;
typedef u_int32_t rpcport_t;
typedef int32_t rpc_inline_t;
#define __dontcare__ -1
#ifndef FALSE
@ -51,12 +63,46 @@
# define NULL 0
#endif
#define mem_alloc(bsize) malloc(bsize)
#define mem_alloc(bsize) calloc(1, bsize)
#define mem_free(ptr, bsize) free(ptr)
#ifndef makedev /* ie, we haven't already included it */
#include <sys/types.h>
#endif
#include <sys/time.h>
#include <netconfig.h>
/*
* The netbuf structure is defined here, because FreeBSD / NetBSD only use
* it inside the RPC code. It's in <xti.h> on SVR4, but it would be confusing
* to have an xti.h, since FreeBSD / NetBSD does not support XTI/TLI.
*/
/*
* The netbuf structure is used for transport-independent address storage.
*/
struct netbuf {
unsigned int maxlen;
unsigned int len;
void *buf;
};
/*
* The format of the addres and options arguments of the XTI t_bind call.
* Only provided for compatibility, it should not be used.
*/
struct t_bind {
struct netbuf addr;
unsigned int qlen;
};
/*
* Internal library and rpcbind use. This is not an exported interface, do
* not use.
*/
struct __rpc_sockinfo {
int si_af;
int si_proto;
int si_socktype;
int si_alen;
};
#endif /* !_RPC_TYPES_H */

View File

@ -1,3 +1,5 @@
/* $NetBSD: xdr.h,v 1.19 2000/07/17 05:00:45 matt Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -97,15 +99,15 @@ enum xdr_op {
*/
typedef struct __rpc_xdr {
enum xdr_op x_op; /* operation; fast additional param */
struct xdr_ops {
const struct xdr_ops {
/* get a long from underlying stream */
bool_t (*x_getlong) __P((struct __rpc_xdr *, long *));
/* put a long to underlying stream */
bool_t (*x_putlong) __P((struct __rpc_xdr *, long *));
/* get some bytes from underlying stream */
bool_t (*x_getbytes) __P((struct __rpc_xdr *, caddr_t, u_int));
/* put some bytes to underlying stream */
bool_t (*x_putbytes) __P((struct __rpc_xdr *, caddr_t, u_int));
/* put a long to " */
bool_t (*x_putlong) __P((struct __rpc_xdr *, const long *));
/* get some bytes from " */
bool_t (*x_getbytes) __P((struct __rpc_xdr *, char *, u_int));
/* put some bytes to " */
bool_t (*x_putbytes) __P((struct __rpc_xdr *, const char *, u_int));
/* returns bytes off from beginning */
u_int (*x_getpostn) __P((struct __rpc_xdr *));
/* lets you reposition the stream */
@ -114,10 +116,11 @@ typedef struct __rpc_xdr {
int32_t *(*x_inline) __P((struct __rpc_xdr *, u_int));
/* free privates of this xdr_stream */
void (*x_destroy) __P((struct __rpc_xdr *));
bool_t (*x_control) __P((struct __rpc_xdr *, int, void *));
} *x_ops;
caddr_t x_public; /* users' data */
caddr_t x_private; /* pointer to private data */
caddr_t x_base; /* private used for position info */
char * x_public; /* users' data */
void * x_private; /* pointer to private data */
char * x_base; /* private used for position info */
int x_handy; /* extra private word */
} XDR;
@ -128,22 +131,17 @@ typedef struct __rpc_xdr {
* The opaque pointer generally points to a structure of the data type
* to be decoded. If this pointer is 0, then the type routines should
* allocate dynamic storage of the appropriate size and return it.
*/
#ifdef _KERNEL
typedef bool_t (*xdrproc_t) __P((XDR *, void *, u_int));
#else
/*
* XXX can't actually prototype it, because some take two args!!!
*
* XXX can't actually prototype it, because some take three args!!!
*/
typedef bool_t (*xdrproc_t) __P((/* XDR *, void *, u_int */));
#endif
/*
* Operations defined on a XDR handle
*
* XDR *xdrs;
* long *longp;
* caddr_t addr;
* char * addr;
* u_int len;
* u_int pos;
*/
@ -157,6 +155,29 @@ typedef bool_t (*xdrproc_t) __P((/* XDR *, void *, u_int */));
#define xdr_putlong(xdrs, longp) \
(*(xdrs)->x_ops->x_putlong)(xdrs, longp)
static __inline int
xdr_getint32(XDR *xdrs, int32_t *ip)
{
long l;
if (!xdr_getlong(xdrs, &l))
return (FALSE);
*ip = (int32_t)l;
return (TRUE);
}
static __inline int
xdr_putint32(XDR *xdrs, int32_t *ip)
{
long l;
l = (long)*ip;
return xdr_putlong(xdrs, &l);
}
#define XDR_GETINT32(xdrs, int32p) xdr_getint32(xdrs, int32p)
#define XDR_PUTINT32(xdrs, int32p) xdr_putint32(xdrs, int32p)
#define XDR_GETBYTES(xdrs, addr, len) \
(*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
#define xdr_getbytes(xdrs, addr, len) \
@ -189,6 +210,21 @@ typedef bool_t (*xdrproc_t) __P((/* XDR *, void *, u_int */));
if ((xdrs)->x_ops->x_destroy) \
(*(xdrs)->x_ops->x_destroy)(xdrs)
#define XDR_CONTROL(xdrs, req, op) \
if ((xdrs)->x_ops->x_control) \
(*(xdrs)->x_ops->x_control)(xdrs, req, op)
#define xdr_control(xdrs, req, op) XDR_CONTROL(xdrs, req, op)
/*
* Solaris strips the '_t' from these types -- not sure why.
* But, let's be compatible.
*/
#define xdr_rpcvers(xdrs, versp) xdr_u_int32(xdrs, versp)
#define xdr_rpcprog(xdrs, progp) xdr_u_int32(xdrs, progp)
#define xdr_rpcproc(xdrs, procp) xdr_u_int32(xdrs, procp)
#define xdr_rpcprot(xdrs, protp) xdr_u_int32(xdrs, protp)
#define xdr_rpcport(xdrs, portp) xdr_u_int32(xdrs, portp)
/*
* Support struct for discriminated unions.
* You create an array of xdrdiscrim structures, terminated with
@ -220,8 +256,13 @@ struct xdr_discrim {
* N.B. and frozen for all time: each data type here uses 4 bytes
* of external representation.
*/
#define IXDR_GET_LONG(buf) ((long)ntohl((u_long)*(buf)++))
#define IXDR_PUT_LONG(buf, v) (*(buf)++ = (long)htonl((u_long)v))
#define IXDR_GET_INT32(buf) ((int32_t)ntohl((u_int32_t)*(buf)++))
#define IXDR_PUT_INT32(buf, v) (*(buf)++ =(int32_t)htonl((u_int32_t)v))
#define IXDR_GET_U_INT32(buf) ((u_int32_t)IXDR_GET_INT32(buf))
#define IXDR_PUT_U_INT32(buf, v) IXDR_PUT_INT32((buf), ((int32_t)(v)))
#define IXDR_GET_LONG(buf) ((long)ntohl((u_int32_t)*(buf)++))
#define IXDR_PUT_LONG(buf, v) (*(buf)++ =(int32_t)htonl((u_int32_t)v))
#define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf))
#define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf))
@ -229,11 +270,11 @@ struct xdr_discrim {
#define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf))
#define IXDR_GET_U_SHORT(buf) ((u_short)IXDR_GET_LONG(buf))
#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), (v))
#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), (v))
#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), (v))
#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), (v))
#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), (v))
/*
* These are the "generic" xdr routines.
@ -256,19 +297,23 @@ extern bool_t xdr_bool __P((XDR *, bool_t *));
extern bool_t xdr_enum __P((XDR *, enum_t *));
extern bool_t xdr_array __P((XDR *, char **, u_int *, u_int, u_int, xdrproc_t));
extern bool_t xdr_bytes __P((XDR *, char **, u_int *, u_int));
extern bool_t xdr_opaque __P((XDR *, caddr_t, u_int));
extern bool_t xdr_opaque __P((XDR *, char *, u_int));
extern bool_t xdr_string __P((XDR *, char **, u_int));
extern bool_t xdr_union __P((XDR *, enum_t *, char *, struct xdr_discrim *, xdrproc_t));
extern unsigned long xdr_sizeof __P((xdrproc_t, void *));
extern bool_t xdr_union __P((XDR *, enum_t *, char *, const struct xdr_discrim *, xdrproc_t));
extern bool_t xdr_char __P((XDR *, char *));
extern bool_t xdr_u_char __P((XDR *, u_char *));
extern bool_t xdr_vector __P((XDR *, char *, u_int, u_int, xdrproc_t));
extern bool_t xdr_float __P((XDR *, float *));
extern bool_t xdr_double __P((XDR *, double *));
extern bool_t xdr_reference __P((XDR *, caddr_t *, u_int, xdrproc_t));
extern bool_t xdr_pointer __P((XDR *, caddr_t *, u_int, xdrproc_t));
extern bool_t xdr_quadruple __P((XDR *, long double *));
extern bool_t xdr_reference __P((XDR *, char **, u_int, xdrproc_t));
extern bool_t xdr_pointer __P((XDR *, char **, u_int, xdrproc_t));
extern bool_t xdr_wrapstring __P((XDR *, char **));
extern void xdr_free __P((xdrproc_t, char *));
extern bool_t xdr_hyper __P((XDR *, quad_t *));
extern bool_t xdr_u_hyper __P((XDR *, u_quad_t *));
extern bool_t xdr_longlong_t __P((XDR *, quad_t *));
extern bool_t xdr_u_longlong_t __P((XDR *, u_quad_t *));
__END_DECLS
/*
@ -291,15 +336,15 @@ __BEGIN_DECLS
/* XDR using memory buffers */
extern void xdrmem_create __P((XDR *, char *, u_int, enum xdr_op));
#ifdef _STDIO_H_
/* XDR using stdio library */
#ifdef _STDIO_H_
extern void xdrstdio_create __P((XDR *, FILE *, enum xdr_op));
#endif
/* XDR pseudo records for tcp */
extern void xdrrec_create __P((XDR *, u_int, u_int, char *,
int (*) __P((caddr_t, caddr_t, int)),
int (*) __P((caddr_t, caddr_t, int))));
int (*) __P((char *, char *, int)),
int (*) __P((char *, char *, int))));
/* make end of xdr record */
extern bool_t xdrrec_endofrecord __P((XDR *, int));
@ -309,6 +354,7 @@ extern bool_t xdrrec_skiprecord __P((XDR *));
/* true if no more input */
extern bool_t xdrrec_eof __P((XDR *));
extern u_int xdrrec_readbytes __P((XDR *, caddr_t, u_int));
__END_DECLS
#endif /* !_RPC_XDR_H */

View File

@ -44,7 +44,7 @@
*/
%/* From: #pragma ident "@(#)key_prot.x 1.7 94/04/29 SMI" */
%
%/* $FreeBSD$ */
%/* Copyright (c) 1990, 1991 Sun Microsystems, Inc. */
%
%/*

View File

@ -1,6 +1,3 @@
/* @(#)nlm_prot.x 2.1 88/08/01 4.0 RPCSRC */
/* @(#)nlm_prot.x 1.8 87/09/21 Copyr 1987 Sun Micro */
/*
* Network lock manager protocol definition
* Copyright (C) 1986 Sun Microsystems, Inc.
@ -12,9 +9,13 @@
%#define LM_MAXSTRLEN 1024
%#define MAXNAMELEN LM_MAXSTRLEN+1
#else
%#include <sys/cdefs.h>
%#ifndef lint
%static const char rcsid[] =
% "$FreeBSD$";
%/*static char sccsid[] = "from: @(#)nlm_prot.x 1.8 87/09/21 Copyr 1987 Sun Micro";*/
%/*static char sccsid[] = "from: * @(#)nlm_prot.x 2.1 88/08/01 4.0 RPCSRC";*/
%__RCSID("$NetBSD: nlm_prot.x,v 1.6 2000/06/07 14:30:15 bouyer Exp $");
%#endif /* not lint */
#endif
@ -77,20 +78,20 @@ struct nlm_lockargs {
};
struct nlm_cancargs {
netobj cookie;
netobj cookie;
bool block;
bool exclusive;
struct nlm_lock alock;
};
struct nlm_testargs {
netobj cookie;
netobj cookie;
bool exclusive;
struct nlm_lock alock;
};
struct nlm_unlockargs {
netobj cookie;
netobj cookie;
struct nlm_lock alock;
};
@ -140,11 +141,127 @@ struct nlm_notify {
long state;
};
#ifdef RPC_HDR
%/* definitions for NLM version 4 */
#endif
enum nlm4_stats {
nlm4_granted = 0,
nlm4_denied = 1,
nlm4_denied_nolock = 2,
nlm4_blocked = 3,
nlm4_denied_grace_period = 4,
nlm4_deadlck = 5,
nlm4_rofs = 6,
nlm4_stale_fh = 7,
nlm4_fbig = 8,
nlm4_failed = 9
};
struct nlm4_stat {
nlm4_stats stat;
};
struct nlm4_holder {
bool exclusive;
u_int32_t svid;
netobj oh;
u_int64_t l_offset;
u_int64_t l_len;
};
struct nlm4_lock {
string caller_name<MAXNAMELEN>;
netobj fh;
netobj oh;
u_int32_t svid;
u_int64_t l_offset;
u_int64_t l_len;
};
struct nlm4_share {
string caller_name<MAXNAMELEN>;
netobj fh;
netobj oh;
fsh_mode mode;
fsh_access access;
};
union nlm4_testrply switch (nlm4_stats stat) {
case nlm_denied:
struct nlm4_holder holder;
default:
void;
};
struct nlm4_testres {
netobj cookie;
nlm4_testrply stat;
};
struct nlm4_testargs {
netobj cookie;
bool exclusive;
struct nlm4_lock alock;
};
struct nlm4_res {
netobj cookie;
nlm4_stat stat;
};
struct nlm4_lockargs {
netobj cookie;
bool block;
bool exclusive;
struct nlm4_lock alock;
bool reclaim; /* used for recovering locks */
int state; /* specify local status monitor state */
};
struct nlm4_cancargs {
netobj cookie;
bool block;
bool exclusive;
struct nlm4_lock alock;
};
struct nlm4_unlockargs {
netobj cookie;
struct nlm4_lock alock;
};
struct nlm4_shareargs {
netobj cookie;
nlm4_share share;
bool reclaim;
};
struct nlm4_shareres {
netobj cookie;
nlm4_stats stat;
int sequence;
};
/*
* argument for the procedure called by rpc.statd when a monitored host
* status change.
* XXX assumes LM_MAXSTRLEN == SM_MAXSTRLEN
*/
struct nlm_sm_status {
string mon_name<LM_MAXSTRLEN>; /* name of host */
int state; /* new state */
opaque priv[16]; /* private data */
};
/*
* Over-the-wire protocol used between the network lock managers
*/
program NLM_PROG {
version NLM_SM {
void NLM_SM_NOTIFY(struct nlm_sm_status) = 1;
} = 0;
version NLM_VERS {
nlm_testres NLM_TEST(struct nlm_testargs) = 1;
@ -180,5 +297,25 @@ program NLM_PROG {
void NLM_FREE_ALL(nlm_notify) = 23;
} = 3;
version NLM_VERS4 {
nlm4_testres NLM4_TEST(nlm4_testargs) = 1;
nlm4_res NLM4_LOCK(nlm4_lockargs) = 2;
nlm4_res NLM4_CANCEL(nlm4_cancargs) = 3;
nlm4_res NLM4_UNLOCK(nlm4_unlockargs) = 4;
nlm4_res NLM4_GRANTED(nlm4_testargs) = 5;
void NLM4_TEST_MSG(nlm4_testargs) = 6;
void NLM4_LOCK_MSG(nlm4_lockargs) = 7;
void NLM4_CANCEL_MSG(nlm4_cancargs) = 8;
void NLM4_UNLOCK_MSG(nlm4_unlockargs) = 9;
void NLM4_GRANTED_MSG(nlm4_testargs) = 10;
void NLM4_TEST_RES(nlm4_testres) = 11;
void NLM4_LOCK_RES(nlm4_res) = 12;
void NLM4_CANCEL_RES(nlm4_res) = 13;
void NLM4_UNLOCK_RES(nlm4_res) = 14;
void NLM4_GRANTED_RES(nlm4_res) = 15;
nlm4_shareres NLM4_SHARE(nlm4_shareargs) = 20;
nlm4_shareres NLM4_UNSHARE(nlm4_shareargs) = 21;
nlm4_res NLM4_NM_LOCK(nlm4_lockargs) = 22;
void NLM4_FREE_ALL(nlm_notify) = 23;
} = 4;
} = 100021;

View File

@ -62,6 +62,7 @@ program SM_PROG {
struct sm_stat SM_UNMON_ALL(struct my_id) = 4;
void SM_SIMU_CRASH(void) = 5;
void SM_NOTIFY(struct stat_chge) = 6;
} = 1;
} = 100024;
@ -90,6 +91,10 @@ struct mon{
opaque priv[16]; /* private information to store at monitor for requesting process */
};
struct stat_chge {
string mon_name<SM_MAXSTRLEN>; /* name of the site that had the state change */
int state;
};
/*
* state # of status monitor monitonically increases each time

View File

@ -26,7 +26,9 @@
* $FreeBSD$
*/
#include <signal.h>
#include <pthread.h>
#include <pthread_np.h>
/*
* Weak symbols: All libc internal usage of these functions should
@ -37,9 +39,13 @@
* between application locks and libc locks (threads holding the
* latter can't be allowed to exit/terminate).
*/
#pragma weak _pthread_cond_init=_pthread_cond_init_stub
#pragma weak _pthread_cond_signal=_pthread_cond_signal_stub
#pragma weak _pthread_cond_wait=_pthread_cond_wait_stub
#pragma weak _pthread_getspecific=_pthread_getspecific_stub
#pragma weak _pthread_key_create=_pthread_key_create_stub
#pragma weak _pthread_key_delete=_pthread_key_delete_stub
#pragma weak _pthread_main_np=_pthread_main_np_stub
#pragma weak _pthread_mutex_destroy=_pthread_mutex_destroy_stub
#pragma weak _pthread_mutex_init=_pthread_mutex_init_stub
#pragma weak _pthread_mutex_lock=_pthread_mutex_lock_stub
@ -50,13 +56,40 @@
#pragma weak _pthread_mutexattr_settype=_pthread_mutexattr_settype_stub
#pragma weak _pthread_once=_pthread_once_stub
#pragma weak _pthread_self=_pthread_self_stub
#pragma weak _pthread_rwlock_init=_pthread_rwlock_init_stub
#pragma weak _pthread_rwlock_rdlock=_pthread_rwlock_rdlock_stub
#pragma weak _pthread_rwlock_tryrdlock=_pthread_rwlock_tryrdlock_stub
#pragma weak _pthread_rwlock_trywrloc=_pthread_rwlock_trywrlock_stub
#pragma weak _pthread_rwlock_unlock=_pthread_rwlock_unlock_stub
#pragma weak _pthread_rwlock_wrlock=_pthread_rwlock_wrlock_stub
#pragma weak _pthread_setspecific=_pthread_setspecific_stub
#pragma weak _pthread_sigmask=_pthread_sigmask_stub
/* Define a null pthread structure just to satisfy _pthread_self. */
struct pthread {
};
static struct pthread main_thread;
int
_pthread_cond_init_stub(pthread_cond_t *cond,
const pthread_condattr_t *cond_attr)
{
return (0);
}
int
_pthread_cond_signal_stub(pthread_cond_t *cond)
{
return (0);
}
int
_pthread_cond_wait_stub(pthread_cond_t *cond,
pthread_mutex_t *mutex)
{
return (0);
}
void *
_pthread_getspecific_stub(pthread_key_t key)
@ -76,6 +109,12 @@ _pthread_key_delete_stub(pthread_key_t key)
return (0);
}
int
_pthread_main_np_stub()
{
return (-1);
}
int
_pthread_mutex_destroy_stub(pthread_mutex_t *mattr)
{
@ -130,6 +169,49 @@ _pthread_once_stub(pthread_once_t *once_control, void (*init_routine) (void))
return (0);
}
int
_pthread_rwlock_init_stub(pthread_rwlock_t *rwlock,
const pthread_rwlockattr_t *attr)
{
return (0);
}
int
_pthread_rwlock_destroy_stub(pthread_rwlock_t *rwlock)
{
return (0);
}
int
_pthread_rwlock_rdlock_stub(pthread_rwlock_t *rwlock)
{
return (0);
}
int
_pthread_rwlock_tryrdlock_stub(pthread_rwlock_t *rwlock)
{
return (0);
}
int
_pthread_rwlock_trywrlock_stub(pthread_rwlock_t *rwlock)
{
return (0);
}
int
_pthread_rwlock_unlock_stub(pthread_rwlock_t *rwlock)
{
return (0);
}
int
_pthread_rwlock_wrlock_stub(pthread_rwlock_t *rwlock)
{
return (0);
}
pthread_t
_pthread_self_stub(void)
{
@ -141,3 +223,14 @@ _pthread_setspecific_stub(pthread_key_t key, const void *value)
{
return (0);
}
int
_pthread_sigmask_stub(int how, const sigset_t *set, sigset_t *oset)
{
/*
* No need to use _sigprocmask, since we know that the threads
* library is not linked in.
*
*/
return (sigprocmask(how, set, oset));
}

View File

@ -58,9 +58,15 @@
#define listen _listen
#define nanosleep _nanosleep
#define open _open
#define poll _poll
#define pthread_cond_signal _pthread_cond_signal
#define pthread_cond_wait _pthread_cond_wait
#define pthread_cond_init _pthread_cond_init
#define pthread_exit _pthread_exit
#define pthread_getspecific _pthread_getspecific
#define pthread_key_create _pthread_key_create
#define pthread_key_delete _pthread_key_delete
#define pthread_main_np _pthread_main_np
#define pthread_mutex_destroy _pthread_mutex_destroy
#define pthread_mutex_init _pthread_mutex_init
#define pthread_mutex_lock _pthread_mutex_lock
@ -70,8 +76,13 @@
#define pthread_mutexattr_destroy _pthread_mutexattr_destroy
#define pthread_mutexattr_settype _pthread_mutexattr_settype
#define pthread_once _pthread_once
#define pthread_rwlock_init _pthread_rwlock_init
#define pthread_rwlock_rdlock _pthread_rwlock_rdlock
#define pthread_rwlock_wrlock _pthread_rwlock_wrlock
#define pthread_rwlock_unlock _pthread_rwlock_unlock
#define pthread_self _pthread_self
#define pthread_setspecific _pthread_setspecific
#define pthread_sigmask _pthread_sigmask
#define read _read
#define readv _readv
#define recvfrom _recvfrom
@ -106,14 +117,9 @@
#define msync _msync
#define nfssvc _nfssvc
#define pause _pause
#define poll _poll
#define pthread_rwlock_destroy _pthread_rwlock_destroy
#define pthread_rwlock_init _pthread_rwlock_init
#define pthread_rwlock_rdlock _pthread_rwlock_rdlock
#define pthread_rwlock_tryrdlock _pthread_rwlock_tryrdlock
#define pthread_rwlock_trywrlock _pthread_rwlock_trywrlock
#define pthread_rwlock_unlock _pthread_rwlock_unlock
#define pthread_rwlock_wrlock _pthread_rwlock_wrlock
#define pthread_rwlockattr_init _pthread_rwlockattr_init
#define pthread_rwlockattr_destroy _pthread_rwlockattr_destroy
#define sched_yield _sched_yield

View File

@ -0,0 +1,130 @@
/*-
* Copyright (c) 1997,98 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by J.T. Conklin.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
* Requirements:
*
* 1. The thread safe mechanism should be lightweight so the library can
* be used by non-threaded applications without unreasonable overhead.
*
* 2. There should be no dependency on a thread engine for non-threaded
* applications.
*
* 3. There should be no dependency on any particular thread engine.
*
* 4. The library should be able to be compiled without support for thread
* safety.
*
*
* Rationale:
*
* One approach for thread safety is to provide discrete versions of the
* library: one thread safe, the other not. The disadvantage of this is
* that libc is rather large, and two copies of a library which are 99%+
* identical is not an efficent use of resources.
*
* Another approach is to provide a single thread safe library. However,
* it should not add significant run time or code size overhead to non-
* threaded applications.
*
* Since the NetBSD C library is used in other projects, it should be
* easy to replace the mutual exclusion primitives with ones provided by
* another system. Similarly, it should also be easy to remove all
* support for thread safety completely if the target environment does
* not support threads.
*
*
* Implementation Details:
*
* The mutex primitives used by the library (mutex_t, mutex_lock, etc.)
* are macros which expand to the cooresponding primitives provided by
* the thread engine or to nothing. The latter is used so that code is
* not unreasonably cluttered with #ifdefs when all thread safe support
* is removed.
*
* The mutex macros can be directly mapped to the mutex primitives from
* pthreads, however it should be reasonably easy to wrap another mutex
* implementation so it presents a similar interface.
*
* Stub implementations of the mutex functions are provided with *weak*
* linkage. These functions simply return success. When linked with a
* thread library (i.e. -lpthread), the functions will override the
* stubs.
*/
#include <pthread.h>
#include <pthread_np.h>
#include "libc_private.h"
#define mutex_t pthread_mutex_t
#define cond_t pthread_cond_t
#define rwlock_t pthread_rwlock_t
#define thread_key_t pthread_key_t
#define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
#define RWLOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER
#define mutex_init(m, a) _pthread_mutex_init(m, a)
#define mutex_lock(m) if (__isthreaded) \
_pthread_mutex_lock(m)
#define mutex_unlock(m) if (__isthreaded) \
_pthread_mutex_unlock(m)
#define mutex_trylock(m) (__isthreaded ? 0 : _pthread_mutex_trylock(m))
#define cond_init(c, a, p) _pthread_cond_init(c, a)
#define cond_signal(m) if (__isthreaded) \
_pthread_cond_signal(m)
#define cond_wait(c, m) if (__isthreaded) \
_pthread_cond_wait(c, m)
#define rwlock_init(l, a) _pthread_rwlock_init(l, a)
#define rwlock_rdlock(l) if (__isthreaded) \
_pthread_rwlock_rdlock(l)
#define rwlock_wrlock(l) if (__isthreaded) \
_pthread_rwlock_wrlock(l)
#define rwlock_unlock(l) if (__isthreaded) \
_pthread_rwlock_unlock(l)
#define thr_keycreate(k, d) _pthread_key_create(k, d)
#define thr_setspecific(k, p) _pthread_setspecific(k, p)
#define thr_getspecific(k) _pthread_getspecific(k)
#define thr_sigsetmask(f, n, o) _pthread_sigmask(f, n, o)
#define thr_self() _pthread_self()
#define thr_exit(x) _pthread_exit(x)
#define thr_main() _pthread_main_np()

View File

@ -1,3 +1,6 @@
/* $NetBSD: DISCLAIMER,v 1.2 1998/01/09 04:11:51 perry Exp $ */
/* $FreeBSD$ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape

View File

@ -1,25 +1,35 @@
# @(#)Makefile 5.11 (Berkeley) 9/6/90
# @(#)Makefile 5.11 (Berkeley) 9/6/90
# $FreeBSD$
.PATH: ${.CURDIR}/../libc/rpc ${.CURDIR}/.
SRCS+= auth_none.c auth_unix.c authunix_prot.c bindresvport.c clnt_bcast.c \
clnt_dg.c clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c \
clnt_vc.c rpc_dtablesize.c getnetconfig.c getnetpath.c getrpcent.c \
getrpcport.c mt_misc.c pmap_clnt.c pmap_getmaps.c pmap_getport.c \
pmap_prot.c pmap_prot2.c pmap_rmt.c rpc_prot.c rpc_commondata.c \
rpc_callmsg.c rpc_generic.c rpc_soc.c rpcb_clnt.c rpcb_prot.c \
rpcb_st_xdr.c svc.c svc_auth.c svc_dg.c svc_auth_unix.c svc_generic.c \
svc_raw.c svc_run.c svc_simple.c svc_vc.c
SRCS+= auth_des.c auth_none.c auth_time.c auth_unix.c \
authdes_prot.c authunix_prot.c bindresvport.c \
clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c clnt_tcp.c \
clnt_udp.c clnt_unix.c crypt_client.c des_crypt.c des_soft.c \
get_myaddress.c getpublickey.c getrpcent.c getrpcport.c \
key_call.c key_prot_xdr.c netname.c netnamer.c \
pmap_clnt.c pmap_getmaps.c pmap_getport.c pmap_prot.c \
pmap_prot2.c pmap_rmt.c rpc_callmsg.c rpc_commondata.c \
rpc_dtablesize.c rpc_prot.c rpcdname.c rtime.c \
svc.c svc_auth.c svc_auth_des.c svc_auth_unix.c \
svc_raw.c svc_run.c svc_simple.c \
svc_tcp.c svc_udp.c svc_unix.c
# XDR
SRCS+= xdr.c xdr_array.c xdr_float.c xdr_mem.c xdr_rec.c xdr_reference.c \
xdr_stdio.c
# Secure-RPC
SRCS+= auth_time.c auth_des.c authdes_prot.c des_crypt.c des_soft.c \
crypt_client.c key_call.c key_prot_xdr.c getpublickey.c \
svc_auth_des.c
# Resolver stuff
SRCS+= netname.c netnamer.c rpcdname.c
# Misc Source
SRCS+= rtime.c
# generated sources
SRCS+= crypt_clnt.c crypt_xdr.c crypt.h
SRCS+= crypt_clnt.c crypt_xdr.c crypt.h
CFLAGS+= -DBROKEN_DES
CFLAGS+= -DBROKEN_DES -DPORTMAP -DDES_BUILTIN
CLEANFILES+= crypt_clnt.c crypt_xdr.c crypt.h
@ -34,79 +44,113 @@ crypt_xdr.c: ${RPCDIR}/crypt.x crypt.h
crypt.h: ${RPCDIR}/crypt.x
${RPCGEN} -h -o ${.TARGET} ${RPCDIR}/crypt.x
.if ${LIB} == "c"
MAN3+= bindresvport.3 des_crypt.3 getrpcent.3 getrpcport.3 publickey.3 rpc.3 \
rpc_secure.3 rtime.3
MAN5+= publickey.5 rpc.5
MAN3+= bindresvport.3 des_crypt.3 getnetconfig.3 getnetpath.3 getrpcent.3 \
getrpcport.3 rpc.3 rpc_soc.3 rpc_clnt_auth.3 rpc_clnt_calls.3 \
rpc_clnt_create.3 rpc_svc_calls.3 rpc_svc_create.3 rpc_svc_err.3 \
rpc_svc_reg.3 rpc_xdr.3 rpcbind.3 xdr.3 publickey.3 rpc_secure.3 \
rtime.3
MAN5+= publickey.5 rpc.5 netconfig.5
MLINKS+= bindresvport.3 bindresvport_sa.3 \
getrpcent.3 endrpcent.3 \
getnetconfig.3 setnetconfig.3 \
getnetconfig.3 getnetconfigent.3 \
getnetconfig.3 endnetconfig.3 \
getnetconfig.3 nc_perror.3 \
getnetconfig.3 nc_sperror.3 \
getnetpath.3 setnetpath.3 \
getnetpath.3 endnetpath.3 \
getrpcent.3 getrpcbyname.3 \
getrpcent.3 getrpcbynumber.3 \
getrpcent.3 endrpcent.3 \
getrpcent.3 setrpcent.3 \
rpc.3 auth_destroy.3 \
rpc.3 authnone_create.3 \
rpc.3 authunix_create.3 \
rpc.3 authunix_create_default.3 \
rpc.3 callrpc.3 \
rpc.3 clnt_broadcast.3 \
rpc.3 clnt_call.3 \
rpc.3 clnt_control.3 \
rpc.3 clnt_create.3 \
rpc.3 clnt_destroy.3 \
rpc.3 clnt_freeres.3 \
rpc.3 clnt_geterr.3 \
rpc.3 clnt_pcreateerror.3 \
rpc.3 clnt_perrno.3 \
rpc.3 clnt_perror.3 \
rpc.3 clnt_spcreateerror.3 \
rpc.3 clnt_sperrno.3 \
rpc.3 clnt_sperror.3 \
rpc.3 clntraw_create.3 \
rpc.3 clnttcp_create.3 \
rpc.3 clntudp_bufcreate.3 \
rpc.3 clntudp_create.3 \
rpc.3 get_myaddress.3 \
rpc.3 pmap_getmaps.3 \
rpc.3 pmap_getport.3 \
rpc.3 pmap_rmtcall.3 \
rpc.3 pmap_set.3 \
rpc.3 pmap_unset.3 \
rpc.3 regsterrpc.3 \
rpc.3 rpc_createerr.3 \
rpc.3 svc_destroy.3 \
rpc.3 svc_fds.3 \
rpc.3 svc_fdset.3 \
rpc.3 svc_getargs.3 \
rpc.3 svc_getcaller.3 \
rpc.3 svc_getreg.3 \
rpc.3 svc_getregset.3 \
rpc.3 svc_register.3 \
rpc.3 svc_run.3 \
rpc.3 svc_sendreply.3 \
rpc.3 svc_unregister.3 \
rpc.3 svcerr_auth.3 \
rpc.3 svcerr_decode.3 \
rpc.3 svcerr_noproc.3 \
rpc.3 svcerr_noprog.3 \
rpc.3 svcerr_progvers.3 \
rpc.3 svcerr_systemerr.3 \
rpc.3 svcerr_weakauth.3 \
rpc.3 svcfd_create.3 \
rpc.3 svcraw_create.3 \
rpc.3 svctcp_create.3 \
rpc.3 svcudp_bufcreate.3 \
rpc.3 xdr_accepted_reply.3 \
rpc.3 xdr_authunix_parms.3 \
rpc.3 xdr_callhdr.3 \
rpc.3 xdr_callmsg.3 \
rpc.3 xdr_opaque_auth.3 \
rpc.3 xdr_pmap.3 \
rpc.3 xdr_pmaplist.3 \
rpc.3 xdr_rejected_reply.3 \
rpc.3 xdr_replymsg.3 \
rpc.3 xprt_register.3 \
rpc.3 xprt_unregister.3
.endif
rpc_clnt_auth.3 auth_destroy.3 \
rpc_clnt_auth.3 authnone_create.3 \
rpc_clnt_auth.3 authsys_create.3 \
rpc_clnt_auth.3 authsys_create_default.3 \
rpc_clnt_calls.3 clnt_call.3 \
rpc_clnt_calls.3 clnt_perrno.3 \
rpc_clnt_calls.3 clnt_perror.3 \
rpc_clnt_calls.3 clnt_sperrno.3 \
rpc_clnt_calls.3 clnt_sperror.3 \
rpc_clnt_calls.3 rpc_call.3 \
rpc_clnt_calls.3 rpc_broadcast.3 \
rpc_clnt_calls.3 rpc_broadcast_exp.3 \
rpc_clnt_calls.3 clnt_freeres.3 \
rpc_clnt_calls.3 clnt_geterr.3 \
rpc_clnt_create.3 clnt_control.3 \
rpc_clnt_create.3 clnt_create.3 \
rpc_clnt_create.3 clnt_create_vers.3 \
rpc_clnt_create.3 clnt_destroy.3 \
rpc_clnt_create.3 clnt_pcreateerror.3 \
rpc_clnt_create.3 clnt_spcreateerror.3 \
rpc_clnt_create.3 clnt_dg_create.3 \
rpc_clnt_create.3 clnt_raw_create.3 \
rpc_clnt_create.3 clnt_tli_create.3 \
rpc_clnt_create.3 clnt_tp_create.3 \
rpc_clnt_create.3 clnt_vc_create.3 \
rpc_svc_calls.3 svc_dg_enablecache.3 \
rpc_svc_calls.3 svc_exit.3 \
rpc_svc_calls.3 svc_freeargs.3 \
rpc_svc_calls.3 svc_getargs.3 \
rpc_svc_calls.3 svc_getreq_common.3 \
rpc_svc_calls.3 svc_getreq_poll.3 \
rpc_svc_calls.3 svc_getreqset.3 \
rpc_svc_calls.3 svc_getrpccaller.3 \
rpc_svc_calls.3 __svc_getcallercreds.3 \
rpc_svc_calls.3 svc_pollset.3 \
rpc_svc_calls.3 svc_run.3 \
rpc_svc_calls.3 svc_sendreply.3 \
rpc_svc_create.3 svc_control.3 \
rpc_svc_create.3 svc_create.3 \
rpc_svc_create.3 svc_dg_create.3 \
rpc_svc_create.3 svc_destroy.3 \
rpc_svc_create.3 svc_fd_create.3 \
rpc_svc_create.3 svc_raw_create.3 \
rpc_svc_create.3 svc_tli_create.3 \
rpc_svc_create.3 svc_tp_create.3 \
rpc_svc_create.3 svc_vc_create.3 \
rpc_svc_err.3 svcerr_auth.3 \
rpc_svc_err.3 svcerr_decode.3 \
rpc_svc_err.3 svcerr_noproc.3 \
rpc_svc_err.3 svcerr_noprog.3 \
rpc_svc_err.3 svcerr_progvers.3 \
rpc_svc_err.3 svcerr_systemerr.3 \
rpc_svc_err.3 svcerr_weakauth.3 \
rpc_svc_reg.3 rpc_reg.3 \
rpc_svc_reg.3 svc_reg.3 \
rpc_svc_reg.3 svc_unreg.3 \
rpc_svc_reg.3 svc_auth_reg.3 \
rpc_svc_reg.3 xprt_register.3 \
rpc_svc_reg.3 xprt_unregister.3 \
rpcbind.3 rpcb_getmaps.3 \
rpcbind.3 rpcb_getaddr.3 \
rpcbind.3 rpcb_gettime.3 \
rpcbind.3 rpcb_rmtcall.3 \
rpcbind.3 rpcb_set.3 \
rpcbind.3 rpcb_unset.3 \
rpc_soc.3 authunix_create.3 \
rpc_soc.3 authunix_create_default.3 \
rpc_soc.3 callrpc.3 \
rpc_soc.3 clnt_broadcast.3 \
rpc_soc.3 clntraw_create.3 \
rpc_soc.3 clnttcp_create.3 \
rpc_soc.3 clntudp_bufcreate.3 \
rpc_soc.3 clntudp_create.3 \
rpc_soc.3 get_myaddress.3 \
rpc_soc.3 pmap_getmaps.3 \
rpc_soc.3 pmap_getport.3 \
rpc_soc.3 pmap_rmtcall.3 \
rpc_soc.3 pmap_set.3 \
rpc_soc.3 pmap_unset.3 \
rpc_soc.3 registerrpc.3 \
rpc_soc.3 rpc_createerr.3 \
rpc_soc.3 svc_fds.3 \
rpc_soc.3 svc_fdset.3 \
rpc_soc.3 svc_getcaller.3 \
rpc_soc.3 svc_register.3 \
rpc_soc.3 svc_unregister.3 \
rpc_soc.3 svcfd_create.3 \
rpc_soc.3 svcraw_create.3 \
rpc_soc.3 svctcp_create.3 \
rpc_soc.3 svcudp_bufcreate.3 \
rpc_soc.3 xdr_pmap.3 \
rpc_soc.3 xdr_pmaplist.3

View File

@ -1,233 +1,176 @@
RPCSRC 4.0 7/11/89
$FreeBSD$
This distribution contains Sun Microsystem's implementation of the
RPC and XDR protocols and is compatible with 4.2BSD and 4.3BSD. Also
included is complete documentation, utilities, RPC service
specification files, and demonstration services in the format used by
the RPC protocol compiler (rpcgen). See WHAT'S NEW below for
details.
PLEASE READ THE DISCLAIMER FILE. DO NOT CALL THE SUN MICROSYSTEMS SUPPORT
LINE WITH QUESTIONS ON THIS RELEASE. THEY CANNOT ANSWER QUESTIONS ABOUT THIS
UNSUPPORTED SOURCE RELEASE.
NOTE ABOUT SECURE RPC:
TIRPCSRC 2.3 29 Aug 1994
This release of RPCSRC contains most of the code needed to implement
Secure RPC (see "DES Authentication" in the RPC Protocol Specification,
doc/rpc.rfc.ms). Due to legal considerations, we are unable to
distribute an implementation of DES, the Data Encryption Standard, which
Secure RPC requires. For this reason, all of the files, documentation, and
programs associated with Secure RPC have been placed into a separate
directory, secure_rpc. The RPC library contained in the main body of this
release *DOES NOT* support Secure RPC. See secure_rpc/README for more
details. (A DES library was posted in Volume 18 of comp.sources.unix.)
This distribution contains SunSoft's implementation of transport-independent
RPC (TI-RPC), External Data Representation (XDR), and various utilities and
documentation. These libraries and programs form the base of Open Network
Computing (ONC), and are derived directly from the Solaris 2.3 source.
If you wish to report bugs found in this release, send mail to:
Previous releases of RPC Source based on SunOS 4.x were ported to 4.2BSD and
used Sockets as the transport interface. These versions were
transport-specific RPC (TS-RPC).
Portable ONC/NFS
Sun Microsystems, Inc
MS 12-33
2550 Garcia Avenue
Mountain View, CA 94043
TI-RPC is an enhanced version of TS-RPC that requires the UNIX System V
Transport Layer Interface (TLI) or an equivalent X/Open Transport Interface
(XTI). TI-RPC is on-the-wire compatible with the TS-RPC, which is supported
by almost 70 vendors on all major operating systems. TS-RPC source code
(RPCSRC 4.0) remains available from several internet sites.
This release is a native source release, that is, it is compatible for
building on Solaris 2.3. This release was built on Solaris 2.3 using SunPro
SPARCompiler 2.0.1.
Solaris 2.3 is based on System V, Release 4 (SVR4), and while this release
should be mostly compatible with other SVR4 systems, some Solaris facilities
that are assumed may not be available. In particular, this release uses the
Makefile format supported by SparcCompiler 2.0.1. Second, the Secure RPC
routines use the Solaris Name Service Switch to access public-key credential
databases. This code will need to be ported if your system does not support
the Name Service Switch. Finally, this release uses the synchronization
interfaces of UI Threads to make certain interfaces thread-safe. These
interfaces are found in libthread in Solaris 2.3 and later.
Applications linked with this release's librpc must link with the United
States domestic version of libcrypt in order to resolve the cbc_crypt() and
ecb_crypt() functions. These routines are used with Secure RPC however all
RPC programs that link with this release's librpc will need to link with the
domestic libcrypt. Note that the Solaris 2.3 Encryption Kit is only available
within the United States. (PLEASE NOTE: The RPC implementation found in
Solaris 2.3's libnsl does *not* have this requirement; linking with libcrypt
is only a requirement for the TIRPCSRC 2.3 version of librpc.)
DOCUMENTATION NOTE
The documentation found in the doc directory are derived from the Solaris 2.3
Network Interfaces Programming Guide. A small number of compile examples are
given, and these use libnsl to link in the RPC library. This release builds
the RPC library as librpc. To use this release's librpc, use the link command
"-lrpc -lnsl -lcrypt". This links the application with TIRPCSRC 2.3's librpc
for RPC routines, Solaris's libnsl for other networking functions, and
libcrypt for the cbc_crypt() and ecb_crypt functions.
WHY IS THIS RELEASE BEING DONE?
This release is being distributed to make the Sun implementation of the ONC
technologies available for reference and porting to non-Solaris platforms.
The current release is a native source distribution, and provides services
that are already available on Solaris 2.3 (such as the RPC headers, the RPC
library in libnsl, rpcbind, rpcinfo, etc.). It is not our intention to
replace these services. See the DISCLAIMER for further information about the
legal status of this release.
WHAT'S NEW IN THIS RELEASE: TIRPCSRC 2.3
The previous release was TIRPCSRC 2.0.
1. This release is based on Solaris 2.3. The previous release was
based on Solaris 2.0. This release contains a siginificant number of
bug fixes and other enhancements over TIRPCSRC 2.0.
2. The RPC library is thread safe for all client-side interfaces
(clnt_create, clnt_call, etc.). The server-side interfaces
(svc_create, svc_run, etc.) are not thread safe in this release. The
server-side interfaces will be made thread safe in the next release of
TIRPCSRC. Please see the manual pages for details about which
interfaces are thread safe.
3. As part of the work to make the RPC library thread-safe, rpcgen has
been enhanced to generate thread-safe RPC stubs (the -M option). Note
that this modifies the call-signature for the stub functions; the
procedure calling the RPC stub must now pass to the stub a pointer to
an allocated structure where results will be placed by the stub. See
the rpcgen manual page and the rpcgen Programming Guide for details.
4. The Remote Asynchronous Calls (RAC) library is now included. RAC was
first introduced in TIRPCSRC 1.0, and was bundled with librpc. It is
now a separate library. The asynchronous call model that RAC provides
can be achieved by using threads for making client-side RPC calls.
The ONC Technology group recommends using threads (where possible) to
achieve asynchrony rather than RAC. See the rpc_rac(3n) manual page
for details.
or send Email to nfsnet@sun.com (the Internet) or sun!nfsnet (Usenet).
ROADMAP
The directory hierarchy is as follows:
demo/ Various demonstration services
demo/dir Remote directory lister
demo/msg Remote console message delivery service
demo/sort Remote sort service
cmd/ Utilities
cmd/rpcgen The RPC Language compiler (for .x files)
cmd/rpcbind The RPC bindery and portmapper
cmd/rpcinfo RPC bindery query utility
cmd/keyserv The Secure RPC keyserver
cmd/demo Some simple ONC demo services
doc/ Documentation for RPC, XDR and NFS in "-ms" format.
doc/ Postscript versions of ONC documentation
etc/ Utilities (rpcinfo and portmap). portmap must be
started by root before any other RPC network services are
used. SEE BELOW FOR BUGFIX TO 4.3BSD COMPILER.
head/ Header files
head/rpcsvc RPCL (.x) specifications for various ONC services, and
header files.
man/ Manual pages for RPC library, rpcgen, and utilities.
lib/ Libraries
lib/librpc The RPC and XDR library
lib/librac The Remote Asynchronous Calls (RAC) library
rpc/ The RPC and XDR library. SEE BELOW
FOR BUGFIX TO 4.2BSD COMPILER.
man/ Manual pages for the RPC library and utilities.
rpcgen/ The RPC Language compiler (for .x files)
uts/common/rpc RPC header files
rpcsvc/ Service definition files for various services and the
server and client code for the Remote Status service.
secure_rpc/ The files in this directory are used to build a version of
the RPC library with DES Authentication. See the README
file in that directory for more details.
BUILD INSTRUCTIONS
Makefiles can be found in all directories except for man. The
Makefile in the top directory will cause these others to be invoked
(except for in the doc, man and demo directories), in turn building the
entire release.
Prior to building the release, you must define the SRC environment variable
to be the path to the top-level Makefile. For example, if /usr/src/tirpcsrc
is where to top-level Makefile is located, execute this command prior to
building the release:
WARNING! THE DEFAULT INSTALLATION PROCEDURES WILL INSTALL FILES
IN /usr/include, /usr/lib, /usr/bin and /etc.
setenv SRC /usr/src/tirpcsrc (csh)
or
SRC=/usr/src/tirpcsrc; export SRC (sh)
The master RPC include file, rpc/rpc.h, is used by all programs and
routines that use RPC. It includes other RPC and system include files
needed by the RPC system. PLEASE NOTE: If your system has NFS, it
may have been based on Sun's NFS Source. The include files installed
by this package may duplicate include files you will find on your NFS
system. The RPCSRC 4.0 include files are upwardly compatible to all
NFS Source include files as of the date of this distribution (not
including any new definitions or declarations added by your system
vendor). HOWEVER: Please read the comments towards the end of
rpc/rpc.h regarding rpc/netdb.h. You may need to uncomment the
inclusion of that file if the structures it defines are already
defined by your system's include files.
The sources in the lib directory depend on header files installed from head
and uts/common/rpc, and the programs in the cmd directory depend on libraries
from lib. Therefore, you should do a "make install" to build the release.
After making any compiler fixes that are needed (see below), at
the top directory, type:
The top-level Makefile builds the release. The "ROOT" macro defines where the
headers and libraries are installed. The default for ROOT is "/proto". You
may change this by either modifiying Makefile.master, or issuing the build
command with a new definition for ROOT:
make install
make install ROOT=/opt/onc
For all installations, the Makefile macro DESTDIR is prepended to the
installation path. It is defined to be null in the Makefiles, so
installations are relative to root. (You will probably need root
privileges for installing the files under the default path.) To
install the files under some other tree (e.g., /usr/local), use the
command:
You will of course need write privileges for the destination directory.
The headers, libraries and executables will be built and installed under the
ROOT.
make install DESTDIR=/usr/local
This will place the include files in /usr/local/usr/include, the RPC
library in /usr/local/usr/lib, rpcgen in /usr/local/usr/bin, and the
utilities in /usr/local/etc. You'll have to edit the Makefiles or
install the files by hand if you want to do anything other than this
kind of relocation of the installation tree.
The RPC library will be built and installed first. By default it is
installed in /usr/lib as "librpclib.a". The directory
/usr/include/rpc will also be created, and several header files will
be installed there. ALL RPC SERVICES INCLUDE THESE HEADER FILES.
The programs in etc/ link in routines from librpclib.a. If you change
where it is installed, be sure to edit etc/'s Makefile to reflect this.
These programs are installed in /etc. PORTMAP MUST BE RUNNING ON
YOUR SYSTEM BEFORE YOU START ANY OTHER RPC SERVICE.
rpcgen is installed in /usr/bin. This program is required to build
the demonstration services in demo and the rstat client and server in
rpcsvc/.
The rpcsvc/ directory will install its files in the directory
/usr/include/rpcsvc. The Remote Status service (rstat_svc) will be
compiled and installed in /etc. If you wish to make this service
available, you should either start this service when needed or have
it started at boot time by invoking it in your /etc/rc.local script.
(Be sure that portmap is started first!) Sun has modified its
version of inetd to automatically start RPC services. (Use "make
LIB=" when building rstat on a Sun Workstation.) The Remote Status
client (rstat) will be installed in /usr/bin. This program queries
the rstat_svc on a remote host and prints a system status summary
similar to the one printed by "uptime".
The documentation is not built during the "make install" command.
Typing "make" in the doc directory will cause all of the manuals to
be formatted using nroff into a single file. We have had a report
that certain "troff" equivalents have trouble processing the full
manual. If you have trouble, try building the manuals individually
(see the Makefile).
The demonstration services in the demo directory are not built by the
top-level "make install" command. To build these, cd to the demo
directory and enter "make". The three services will be built.
top-level "make install" command. To build these, cd to the cmd/demo
directory and enter "make". The four services will be built.
RPCGEN MUST BE INSTALLED in a path that make can find. To run the
services, start the portmap program as root and invoke the service
services, rpcbind must be running, then invoke the service
(you probably will want to put it in the background). rpcinfo can be
used to check that the service succeeded in getting registered with
portmap, and to ping the service (see rpcinfo's man page). You can
rpcbind, and to ping the service (see rpcinfo's man page). You can
then use the corresponding client program to exercise the service.
To build these services on a Sun workstation, you must prevent the
Makefile from trying to link the RPC library (as these routines are
already a part of Sun's libc). Use: "make LIB=".
BUGFIX FOR 4.3BSD COMPILER
The use of a 'void *' declaration for one of the arguments in
the reply_proc() procedure in etc/rpcinfo.c will trigger a bug
in the 4.3BSD compiler. The bug is fixed by the following change to
the compiler file mip/manifest.h:
BUILDING ONC APPLICATIONS
*** manifest.h.r1.1 Thu Apr 30 13:52:25 1987
--- manifest.h.r1.2 Mon Nov 23 18:58:17 1987
***************
*** 21,27 ****
/*
* Bogus type values
*/
! #define TNULL PTR /* pointer to UNDEF */
#define TVOID FTN /* function returning UNDEF (for void) */
/*
--- 21,27 ----
/*
* Bogus type values
*/
! #define TNULL INCREF(MOETY) /* pointer to MOETY -- impossible type */
#define TVOID FTN /* function returning UNDEF (for void) */
/*
See the Makefiles in the demonstration services for examples of building
ONC applications with this release. The $(ROOT)/usr/include directory
must be included in the compiler header file search path (-I), and the
$(ROOT)/usr/lib directory must be included in the linker library file search
path (-L). Also, to run executables built dynamically, the shared library
search path (LD_LIBRARY_PATH) must also include $(ROOT)/usr/lib. In addition
to linking in this release's librpc (via -lrpc), you must also link with
Solaris's libnsl (-lnsl) and the US domestic version of libcrypt (-lcrypt).
If you cannot fix your compiler, change the declaration in reply_proc()
from 'void *' to 'char *'.
BUGFIX FOR 4.2BSD COMPILER
Unpatched 4.2BSD compilers complain about valid C. You can make old
compilers happy by changing some voids to ints. However, the fix to
the 4.2 VAX compiler is as follows (to mip/trees.c):
*** trees.c.r1.1 Mon May 11 13:47:58 1987
--- trees.c.r1.2 Wed Jul 2 18:28:52 1986
***************
*** 1247,1253 ****
if(o==CAST && mt1==0)return(TYPL+TYMATCH);
if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );
else if( (mt1&MENU)||(mt2&MENU) ) return( LVAL+NCVT+TYPL+PTMATCH+PUN );
! else if( mt12 == 0 ) break;
else if( mt1 & MPTR ) return( LVAL+PTMATCH+PUN );
else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
break;
--- 1261,1269 ----
if(o==CAST && mt1==0)return(TYPL+TYMATCH);
if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );
else if( (mt1&MENU)||(mt2&MENU) ) return( LVAL+NCVT+TYPL+PTMATCH+PUN );
! /* if right is TVOID and looks like a CALL, is not ok */
! else if (mt2 == 0 && (p->in.right->in.op == CALL || p->in.right->in.op == UNARY CALL))
! break;
else if( mt1 & MPTR ) return( LVAL+PTMATCH+PUN );
else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
break;
WHAT'S NEW IN THIS RELEASE: RPCSRC 4.0
The previous release was RPCSRC 3.9. As with all previous releases,
this release is based directly on files from Sun Microsystem's
implementation.
Upgrade from RPCSRC 3.9
1) RPCSRC 4.0 upgrades RPCSRC 3.9. Improvements from SunOS 4.0 have
been integrated into this release.
Secure RPC (in the secure_rpc/ directory)
2) DES Authentication routines and programs are provided.
3) A new manual, "Secure NFS" is provided, which describes Secure RPC
and Secure NFS.
4) Skeleton routines and manual pages are provided which describe the
DES encryption procedures required by Secure RPC. HOWEVER, NO DES
ROUTINE IS PROVIDED.
New Functionality
5) rpcinfo can now be used to de-register services from the portmapper
which may have terminated abnormally.
6) A new client, rstat, is provided which queries the rstat_svc and
prints a status line similar to the one displayed by "uptime".

View File

@ -1,3 +1,4 @@
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -32,59 +33,58 @@
/*
* auth_des.c, client-side implementation of DES authentication
*/
#include "reentrant.h"
#include "namespace.h"
#include <err.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/cdefs.h>
#include <rpc/des_crypt.h>
#include <syslog.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
#include <rpc/auth_des.h>
#include <rpc/clnt.h>
#include <rpc/xdr.h>
#include <netinet/in.h> /* XXX: just to get htonl() and ntohl() */
#include <sys/socket.h>
#undef NIS
#include <rpcsvc/nis.h>
#include "un-namespace.h"
#if defined(LIBC_SCCS) && !defined(lint)
/* from: static char sccsid[] = "@(#)auth_des.c 2.2 88/07/29 4.0 RPCSRC; from 1.9 88/02/08 SMI"; */
static const char rcsid[] = "$FreeBSD$";
#endif
extern bool_t __rpc_get_time_offset __P(( struct timeval *, nis_server *,
char *, char **, struct sockaddr_in * ));
extern int rtime __P(( struct sockaddr_in *, struct timeval *, struct timeval *));
extern bool_t xdr_authdes_cred __P(( XDR *, struct authdes_cred * ));
extern bool_t xdr_authdes_verf __P(( XDR *, struct authdes_verf * ));
#define MILLION 1000000L
#define RTIME_TIMEOUT 5 /* seconds to wait for sync */
#define USEC_PER_SEC 1000000
#define RTIME_TIMEOUT 5 /* seconds to wait for sync */
#define AUTH_PRIVATE(auth) (struct ad_private *) auth->ah_private
#define ALLOC(object_type) (object_type *) mem_alloc(sizeof(object_type))
#define FREE(ptr, size) mem_free((char *)(ptr), (int) size)
#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE)
#define debug(msg) /*printf("%s\n", msg) */
extern bool_t xdr_authdes_cred( XDR *, struct authdes_cred *);
extern bool_t xdr_authdes_verf( XDR *, struct authdes_verf *);
extern int key_encryptsession_pk();
extern bool_t __rpc_get_time_offset(struct timeval *, nis_server *, char *,
char **, char **);
/*
* DES authenticator operations vector
*/
static void authdes_nextverf();
static bool_t authdes_marshal();
static bool_t authdes_validate();
static bool_t authdes_refresh();
static void authdes_destroy();
static struct auth_ops authdes_ops = {
authdes_nextverf,
authdes_marshal,
authdes_validate,
authdes_refresh,
authdes_destroy
};
#ifdef foo
static bool_t synchronize __P(( struct sockaddr *, struct timeval *));
#endif
static void authdes_nextverf(AUTH *);
static bool_t authdes_marshal(AUTH *, XDR *);
static bool_t authdes_validate(AUTH *, struct opaque_auth *);
static bool_t authdes_refresh(AUTH *, void *);
static void authdes_destroy(AUTH *);
static struct auth_ops *authdes_ops(void);
/*
* This struct is pointed to by the ah_private field of an "AUTH *"
*/
@ -95,10 +95,10 @@ struct ad_private {
u_int ad_servernamelen; /* length of name, rounded up */
u_int ad_window; /* client specified window */
bool_t ad_dosync; /* synchronize? */
struct sockaddr ad_syncaddr; /* remote host to synch with */
struct netbuf ad_syncaddr; /* remote host to synch with */
char *ad_timehost; /* remote host to synch with */
struct timeval ad_timediff; /* server's time - client's time */
u_long ad_nickname; /* server's nickname for client */
u_int ad_nickname; /* server's nickname for client */
struct authdes_cred ad_cred; /* storage for credential */
struct authdes_verf ad_verf; /* storage for verifier */
struct timeval ad_timestamp; /* timestamp sent */
@ -108,106 +108,50 @@ struct ad_private {
char *ad_uaddr; /* Timehost uaddr */
nis_server *ad_nis_srvr; /* NIS+ server struct */
};
AUTH *authdes_pk_seccreate(const char *, netobj *, u_int, const char *,
const des_block *, nis_server *);
/*
* Create the client des authentication object
*/
* documented version of authdes_seccreate
*/
/*
servername: network name of server
win: time to live
timehost: optional hostname to sync with
ckey: optional conversation key to use
*/
AUTH *
authdes_create(servername, window, syncaddr, ckey)
char *servername; /* network name of server */
u_int window; /* time to live */
struct sockaddr *syncaddr; /* optional addr of host to sync with */
des_block *ckey; /* optional conversation key to use*/
authdes_seccreate(const char *servername, const u_int win,
const char *timehost, const des_block *ckey)
{
u_char pkey_data[1024];
netobj pkey;
AUTH *dummy;
AUTH *auth;
struct ad_private *ad;
char namebuf[MAXNETNAMELEN+1];
u_char pkey_data[1024];
if (!getpublickey(servername, pkey_data))
return(NULL);
/*
* Allocate everything now
*/
auth = ALLOC(AUTH);
ad = ALLOC(struct ad_private);
(void) getnetname(namebuf);
ad->ad_fullnamelen = RNDUP(strlen(namebuf));
ad->ad_fullname = (char *)mem_alloc(ad->ad_fullnamelen + 1);
ad->ad_servernamelen = strlen(servername);
ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1);
if (auth == NULL || ad == NULL || ad->ad_fullname == NULL ||
ad->ad_servername == NULL) {
debug("authdes_create: out of memory");
goto failed;
if (! getpublickey(servername, (char *) pkey_data)) {
syslog(LOG_ERR,
"authdes_seccreate: no public key found for %s",
servername);
return (NULL);
}
/*
* Set up private data
*/
bcopy(namebuf, ad->ad_fullname, ad->ad_fullnamelen + 1);
bcopy(servername, ad->ad_servername, ad->ad_servernamelen + 1);
bcopy(pkey_data, ad->ad_pkey, strlen(pkey_data) + 1);
if (syncaddr != NULL) {
ad->ad_syncaddr = *syncaddr;
ad->ad_dosync = TRUE;
} else {
ad->ad_dosync = FALSE;
}
ad->ad_window = window;
if (ckey == NULL) {
if (key_gendes(&auth->ah_key) < 0) {
debug("authdes_create: unable to gen conversation key");
return (NULL);
}
} else {
auth->ah_key = *ckey;
}
/*
* Set up auth handle
*/
auth->ah_cred.oa_flavor = AUTH_DES;
auth->ah_verf.oa_flavor = AUTH_DES;
auth->ah_ops = &authdes_ops;
auth->ah_private = (caddr_t)ad;
if (!authdes_refresh(auth)) {
goto failed;
}
return (auth);
failed:
if (auth != NULL)
FREE(auth, sizeof(AUTH));
if (ad != NULL)
FREE(ad, sizeof(struct ad_private));
if (ad->ad_fullname != NULL)
FREE(ad->ad_fullname, ad->ad_fullnamelen + 1);
if (ad->ad_servername != NULL)
FREE(ad->ad_servername, ad->ad_servernamelen + 1);
return (NULL);
pkey.n_bytes = (char *) pkey_data;
pkey.n_len = (u_int)strlen((char *)pkey_data) + 1;
dummy = authdes_pk_seccreate(servername, &pkey, win, timehost,
ckey, NULL);
return (dummy);
}
/*
* Slightly modified version of authdes_create which takes the public key
* Slightly modified version of authdessec_create which takes the public key
* of the server principal as an argument. This spares us a call to
* getpublickey() which in the nameserver context can cause a deadlock.
*/
AUTH *
authdes_pk_create(servername, pkey, window, timehost, ckey, srvr)
char *servername; /* network name of server */
netobj *pkey; /* public key of server */
u_int window; /* time to live */
char *timehost; /* optional hostname to sync with */
des_block *ckey; /* optional conversation key to use */
nis_server *srvr; /* optional NIS+ server struct */
authdes_pk_seccreate(const char *servername, netobj *pkey, u_int window,
const char *timehost, const des_block *ckey, nis_server *srvr)
{
AUTH *auth;
struct ad_private *ad;
@ -218,12 +162,12 @@ authdes_pk_create(servername, pkey, window, timehost, ckey, srvr)
*/
auth = ALLOC(AUTH);
if (auth == NULL) {
debug("authdes_pk_create: out of memory");
syslog(LOG_ERR, "authdes_pk_seccreate: out of memory");
return (NULL);
}
ad = ALLOC(struct ad_private);
if (ad == NULL) {
debug("authdes_pk_create: out of memory");
syslog(LOG_ERR, "authdes_pk_seccreate: out of memory");
goto failed;
}
ad->ad_fullname = ad->ad_servername = NULL; /* Sanity reasons */
@ -242,13 +186,13 @@ authdes_pk_create(servername, pkey, window, timehost, ckey, srvr)
ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1);
if (ad->ad_fullname == NULL || ad->ad_servername == NULL) {
debug("authdes_pk_create: out of memory");
syslog(LOG_ERR, "authdes_seccreate: out of memory");
goto failed;
}
if (timehost != NULL) {
ad->ad_timehost = (char *)mem_alloc(strlen(timehost) + 1);
if (ad->ad_timehost == NULL) {
debug("authdes_pk_create: out of memory");
syslog(LOG_ERR, "authdes_seccreate: out of memory");
goto failed;
}
memcpy(ad->ad_timehost, timehost, strlen(timehost) + 1);
@ -264,7 +208,8 @@ authdes_pk_create(servername, pkey, window, timehost, ckey, srvr)
ad->ad_window = window;
if (ckey == NULL) {
if (key_gendes(&auth->ah_key) < 0) {
debug("authdes_pk_create: unable to gen conversation key");
syslog(LOG_ERR,
"authdes_seccreate: keyserv(1m) is unable to generate session key");
goto failed;
}
} else {
@ -276,10 +221,10 @@ authdes_pk_create(servername, pkey, window, timehost, ckey, srvr)
*/
auth->ah_cred.oa_flavor = AUTH_DES;
auth->ah_verf.oa_flavor = AUTH_DES;
auth->ah_ops = &authdes_ops;
auth->ah_ops = authdes_ops();
auth->ah_private = (caddr_t)ad;
if (!authdes_refresh(auth)) {
if (!authdes_refresh(auth, NULL)) {
goto failed;
}
ad->ad_nis_srvr = NULL; /* not needed any longer */
@ -296,13 +241,14 @@ authdes_pk_create(servername, pkey, window, timehost, ckey, srvr)
if (ad->ad_timehost)
FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1);
if (ad->ad_netid)
free(ad->ad_netid);
FREE(ad->ad_netid, strlen(ad->ad_netid) + 1);
if (ad->ad_uaddr)
free(ad->ad_uaddr);
FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1);
FREE(ad, sizeof (struct ad_private));
}
return (NULL);
}
/*
* Implement the five authentication operations
*/
@ -313,30 +259,27 @@ authdes_pk_create(servername, pkey, window, timehost, ckey, srvr)
*/
/*ARGSUSED*/
static void
authdes_nextverf(auth)
AUTH *auth;
authdes_nextverf(AUTH *auth)
{
/* what the heck am I supposed to do??? */
}
/*
* 2. Marshal
*/
static bool_t
authdes_marshal(auth, xdrs)
AUTH *auth;
XDR *xdrs;
authdes_marshal(AUTH *auth, XDR *xdrs)
{
/* LINTED pointer alignment */
struct ad_private *ad = AUTH_PRIVATE(auth);
struct authdes_cred *cred = &ad->ad_cred;
struct authdes_verf *verf = &ad->ad_verf;
des_block cryptbuf[2];
des_block ivec;
int status;
long len;
int32_t *ixdr;
int len;
register rpc_inline_t *ixdr;
/*
* Figure out the "time", accounting for any time difference
@ -345,30 +288,32 @@ authdes_marshal(auth, xdrs)
(void) gettimeofday(&ad->ad_timestamp, (struct timezone *)NULL);
ad->ad_timestamp.tv_sec += ad->ad_timediff.tv_sec;
ad->ad_timestamp.tv_usec += ad->ad_timediff.tv_usec;
if (ad->ad_timestamp.tv_usec >= MILLION) {
ad->ad_timestamp.tv_usec -= MILLION;
ad->ad_timestamp.tv_sec += 1;
while (ad->ad_timestamp.tv_usec >= USEC_PER_SEC) {
ad->ad_timestamp.tv_usec -= USEC_PER_SEC;
ad->ad_timestamp.tv_sec++;
}
/*
* XDR the timestamp and possibly some other things, then
* encrypt them.
*/
ixdr = (int32_t *)cryptbuf;
IXDR_PUT_LONG(ixdr, ad->ad_timestamp.tv_sec);
IXDR_PUT_LONG(ixdr, ad->ad_timestamp.tv_usec);
ixdr = (rpc_inline_t *)cryptbuf;
IXDR_PUT_INT32(ixdr, ad->ad_timestamp.tv_sec);
IXDR_PUT_INT32(ixdr, ad->ad_timestamp.tv_usec);
if (ad->ad_cred.adc_namekind == ADN_FULLNAME) {
IXDR_PUT_U_LONG(ixdr, ad->ad_window);
IXDR_PUT_U_LONG(ixdr, ad->ad_window - 1);
IXDR_PUT_U_INT32(ixdr, ad->ad_window);
IXDR_PUT_U_INT32(ixdr, ad->ad_window - 1);
ivec.key.high = ivec.key.low = 0;
status = cbc_crypt((char *)&auth->ah_key, (char *)cryptbuf,
2*sizeof(des_block), DES_ENCRYPT | DES_HW, (char *)&ivec);
(u_int) 2 * sizeof (des_block),
DES_ENCRYPT | DES_HW, (char *)&ivec);
} else {
status = ecb_crypt((char *)&auth->ah_key, (char *)cryptbuf,
sizeof(des_block), DES_ENCRYPT | DES_HW);
(u_int) sizeof (des_block),
DES_ENCRYPT | DES_HW);
}
if (DES_FAILED(status)) {
debug("authdes_marshal: DES encryption failure");
syslog(LOG_ERR, "authdes_marshal: DES encryption failure");
return (FALSE);
}
ad->ad_verf.adv_xtimestamp = cryptbuf[0];
@ -391,21 +336,21 @@ authdes_marshal(auth, xdrs)
}
if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) {
IXDR_PUT_LONG(ixdr, AUTH_DES);
IXDR_PUT_LONG(ixdr, len);
IXDR_PUT_INT32(ixdr, AUTH_DES);
IXDR_PUT_INT32(ixdr, len);
} else {
ATTEMPT(xdr_putlong(xdrs, (long *)&auth->ah_cred.oa_flavor));
ATTEMPT(xdr_putlong(xdrs, &len));
ATTEMPT(xdr_putint32(xdrs, (int *)&auth->ah_cred.oa_flavor));
ATTEMPT(xdr_putint32(xdrs, &len));
}
ATTEMPT(xdr_authdes_cred(xdrs, cred));
len = (2 + 1)*BYTES_PER_XDR_UNIT;
if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) {
IXDR_PUT_LONG(ixdr, AUTH_DES);
IXDR_PUT_LONG(ixdr, len);
IXDR_PUT_INT32(ixdr, AUTH_DES);
IXDR_PUT_INT32(ixdr, len);
} else {
ATTEMPT(xdr_putlong(xdrs, (long *)&auth->ah_verf.oa_flavor));
ATTEMPT(xdr_putlong(xdrs, &len));
ATTEMPT(xdr_putint32(xdrs, (int *)&auth->ah_verf.oa_flavor));
ATTEMPT(xdr_putint32(xdrs, &len));
}
ATTEMPT(xdr_authdes_verf(xdrs, verf));
return (TRUE);
@ -416,89 +361,92 @@ authdes_marshal(auth, xdrs)
* 3. Validate
*/
static bool_t
authdes_validate(auth, rverf)
AUTH *auth;
struct opaque_auth *rverf;
authdes_validate(AUTH *auth, struct opaque_auth *rverf)
{
/* LINTED pointer alignment */
struct ad_private *ad = AUTH_PRIVATE(auth);
struct authdes_verf verf;
int status;
register u_long *ixdr;
register uint32_t *ixdr;
des_block buf;
if (rverf->oa_length != (2 + 1) * BYTES_PER_XDR_UNIT) {
return (FALSE);
}
ixdr = (u_long *)rverf->oa_base;
verf.adv_xtimestamp.key.high = (u_long)*ixdr++;
verf.adv_xtimestamp.key.low = (u_long)*ixdr++;
verf.adv_int_u = (u_long)*ixdr++; /* nickname not XDR'd ! */
/* LINTED pointer alignment */
ixdr = (uint32_t *)rverf->oa_base;
buf.key.high = (uint32_t)*ixdr++;
buf.key.low = (uint32_t)*ixdr++;
verf.adv_int_u = (uint32_t)*ixdr++;
/*
* Decrypt the timestamp
*/
status = ecb_crypt((char *)&auth->ah_key, (char *)&verf.adv_xtimestamp,
sizeof(des_block), DES_DECRYPT | DES_HW);
status = ecb_crypt((char *)&auth->ah_key, (char *)&buf,
(u_int)sizeof (des_block), DES_DECRYPT | DES_HW);
if (DES_FAILED(status)) {
debug("authdes_validate: DES decryption failure");
syslog(LOG_ERR, "authdes_validate: DES decryption failure");
return (FALSE);
}
/*
* xdr the decrypted timestamp
* xdr the decrypted timestamp
*/
ixdr = (u_long *)verf.adv_xtimestamp.c;
verf.adv_timestamp.tv_sec = IXDR_GET_LONG(ixdr) + 1;
verf.adv_timestamp.tv_usec = IXDR_GET_LONG(ixdr);
/* LINTED pointer alignment */
ixdr = (uint32_t *)buf.c;
verf.adv_timestamp.tv_sec = IXDR_GET_INT32(ixdr) + 1;
verf.adv_timestamp.tv_usec = IXDR_GET_INT32(ixdr);
/*
* validate
*/
if (bcmp((char *)&ad->ad_timestamp, (char *)&verf.adv_timestamp,
sizeof(struct timeval)) != 0) {
debug("authdes_validate: verifier mismatch\n");
syslog(LOG_DEBUG, "authdes_validate: verifier mismatch");
return (FALSE);
}
/*
* We have a nickname now, let's use it
*/
ad->ad_nickname = verf.adv_nickname;
ad->ad_cred.adc_namekind = ADN_NICKNAME;
return (TRUE);
ad->ad_nickname = verf.adv_nickname;
ad->ad_cred.adc_namekind = ADN_NICKNAME;
return (TRUE);
}
/*
* 4. Refresh
*/
/*ARGSUSED*/
static bool_t
authdes_refresh(auth)
AUTH *auth;
authdes_refresh(AUTH *auth, void *dummy)
{
/* LINTED pointer alignment */
struct ad_private *ad = AUTH_PRIVATE(auth);
struct authdes_cred *cred = &ad->ad_cred;
int ok;
netobj pkey;
if (ad->ad_dosync &&
#ifdef old
!synchronize(&ad->ad_syncaddr, &ad->ad_timediff)) {
#else
!__rpc_get_time_offset(&ad->ad_timediff,ad->ad_nis_srvr,
ad->ad_timehost, &(ad->ad_uaddr),
(struct sockaddr_in *)&(ad->ad_syncaddr))) {
#endif
/*
* Hope the clocks are synced!
*/
ad->ad_timediff.tv_sec = ad->ad_timediff.tv_usec = 0;
ad->ad_dosync = 0;
debug("authdes_refresh: unable to synchronize with server");
if (ad->ad_dosync) {
ok = __rpc_get_time_offset(&ad->ad_timediff, ad->ad_nis_srvr,
ad->ad_timehost, &(ad->ad_uaddr),
&(ad->ad_netid));
if (! ok) {
/*
* Hope the clocks are synced!
*/
ad->ad_dosync = 0;
syslog(LOG_DEBUG,
"authdes_refresh: unable to synchronize clock");
}
}
ad->ad_xkey = auth->ah_key;
pkey.n_bytes = (char *)(ad->ad_pkey);
pkey.n_len = strlen((char *)ad->ad_pkey) + 1;
pkey.n_len = (u_int)strlen((char *)ad->ad_pkey) + 1;
if (key_encryptsession_pk(ad->ad_servername, &pkey, &ad->ad_xkey) < 0) {
debug("authdes_create: unable to encrypt conversation key");
syslog(LOG_INFO,
"authdes_refresh: keyserv(1m) is unable to encrypt session key");
return (FALSE);
}
cred->adc_fullname.key = ad->ad_xkey;
@ -512,43 +460,39 @@ authdes_refresh(auth)
* 5. Destroy
*/
static void
authdes_destroy(auth)
AUTH *auth;
authdes_destroy(AUTH *auth)
{
/* LINTED pointer alignment */
struct ad_private *ad = AUTH_PRIVATE(auth);
FREE(ad->ad_fullname, ad->ad_fullnamelen + 1);
FREE(ad->ad_servername, ad->ad_servernamelen + 1);
FREE(ad, sizeof(struct ad_private));
if (ad->ad_timehost)
FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1);
if (ad->ad_netid)
FREE(ad->ad_netid, strlen(ad->ad_netid) + 1);
if (ad->ad_uaddr)
FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1);
FREE(ad, sizeof (struct ad_private));
FREE(auth, sizeof(AUTH));
}
#ifdef old
/*
* Synchronize with the server at the given address, that is,
* adjust timep to reflect the delta between our clocks
*/
static bool_t
synchronize(syncaddr, timep)
struct sockaddr *syncaddr;
struct timeval *timep;
static struct auth_ops *
authdes_ops(void)
{
struct timeval mytime;
struct timeval timeout;
static struct auth_ops ops;
extern mutex_t authdes_ops_lock;
timeout.tv_sec = RTIME_TIMEOUT;
timeout.tv_usec = 0;
if (rtime((struct sockaddr_in *)syncaddr, timep, NULL /*&timeout*/) < 0) {
return (FALSE);
}
(void) gettimeofday(&mytime, (struct timezone *)NULL);
timep->tv_sec -= mytime.tv_sec;
if (mytime.tv_usec > timep->tv_usec) {
timep->tv_sec -= 1;
timep->tv_usec += MILLION;
}
timep->tv_usec -= mytime.tv_usec;
return (TRUE);
/* VARIABLES PROTECTED BY ops_lock: ops */
mutex_lock(&authdes_ops_lock);
if (ops.ah_nextverf == NULL) {
ops.ah_nextverf = authdes_nextverf;
ops.ah_marshal = authdes_marshal;
ops.ah_validate = authdes_validate;
ops.ah_refresh = authdes_refresh;
ops.ah_destroy = authdes_destroy;
}
mutex_unlock(&authdes_ops_lock);
return (&ops);
}
#endif

View File

@ -1,3 +1,5 @@
/* $NetBSD: auth_none.c,v 1.13 2000/01/22 22:19:17 mycroft Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -27,10 +29,11 @@
* Mountain View, California 94043
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)auth_none.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *rcsid = "$FreeBSD$";
static char *sccsid = "@(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";
static char *sccsid = "@(#)auth_none.c 2.1 88/07/29 4.0 RPCSRC";
#endif
/*
@ -41,96 +44,135 @@ static char *rcsid = "$FreeBSD$";
* Copyright (C) 1984, Sun Microsystems, Inc.
*/
#include "reentrant.h"
#include "namespace.h"
#include <assert.h>
#include <stdlib.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
#define MAX_MARSHEL_SIZE 20
#include "un-namespace.h"
#define MAX_MARSHAL_SIZE 20
/*
* Authenticator operations routines
*/
static void authnone_verf();
static void authnone_destroy();
static bool_t authnone_marshal();
static bool_t authnone_validate();
static bool_t authnone_refresh();
static struct auth_ops ops = {
authnone_verf,
authnone_marshal,
authnone_validate,
authnone_refresh,
authnone_destroy
};
static bool_t authnone_marshal (AUTH *, XDR *);
static void authnone_verf (AUTH *);
static bool_t authnone_validate (AUTH *, struct opaque_auth *);
static bool_t authnone_refresh (AUTH *, void *);
static void authnone_destroy (AUTH *);
extern bool_t xdr_opaque_auth();
static struct auth_ops *authnone_ops();
static struct authnone_private {
AUTH no_client;
char marshalled_client[MAX_MARSHEL_SIZE];
char marshalled_client[MAX_MARSHAL_SIZE];
u_int mcnt;
} *authnone_private;
AUTH *
authnone_create()
{
register struct authnone_private *ap = authnone_private;
struct authnone_private *ap = authnone_private;
XDR xdr_stream;
register XDR *xdrs;
XDR *xdrs;
extern mutex_t authnone_lock;
mutex_lock(&authnone_lock);
if (ap == 0) {
ap = (struct authnone_private *)calloc(1, sizeof (*ap));
if (ap == 0)
if (ap == 0) {
mutex_unlock(&authnone_lock);
return (0);
}
authnone_private = ap;
}
if (!ap->mcnt) {
ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth;
ap->no_client.ah_ops = &ops;
ap->no_client.ah_ops = authnone_ops();
xdrs = &xdr_stream;
xdrmem_create(xdrs, ap->marshalled_client, (u_int)MAX_MARSHEL_SIZE,
XDR_ENCODE);
xdrmem_create(xdrs, ap->marshalled_client,
(u_int)MAX_MARSHAL_SIZE, XDR_ENCODE);
(void)xdr_opaque_auth(xdrs, &ap->no_client.ah_cred);
(void)xdr_opaque_auth(xdrs, &ap->no_client.ah_verf);
ap->mcnt = XDR_GETPOS(xdrs);
XDR_DESTROY(xdrs);
}
mutex_unlock(&authnone_lock);
return (&ap->no_client);
}
/*ARGSUSED*/
static bool_t
authnone_marshal(client, xdrs)
AUTH *client;
XDR *xdrs;
authnone_marshal(AUTH *client, XDR *xdrs)
{
register struct authnone_private *ap = authnone_private;
struct authnone_private *ap;
bool_t dummy;
extern mutex_t authnone_lock;
if (ap == 0)
return (0);
return ((*xdrs->x_ops->x_putbytes)(xdrs,
ap->marshalled_client, ap->mcnt));
assert(xdrs != NULL);
ap = authnone_private;
if (ap == NULL) {
mutex_unlock(&authnone_lock);
return (FALSE);
}
dummy = (*xdrs->x_ops->x_putbytes)(xdrs,
ap->marshalled_client, ap->mcnt);
mutex_unlock(&authnone_lock);
return (dummy);
}
/* All these unused parameters are required to keep ANSI-C from grumbling */
/*ARGSUSED*/
static void
authnone_verf()
authnone_verf(AUTH *client)
{
}
/*ARGSUSED*/
static bool_t
authnone_validate()
authnone_validate(AUTH *client, struct opaque_auth *opaque)
{
return (TRUE);
}
/*ARGSUSED*/
static bool_t
authnone_refresh()
authnone_refresh(AUTH *client, void *dummy)
{
return (FALSE);
}
/*ARGSUSED*/
static void
authnone_destroy()
authnone_destroy(AUTH *client)
{
}
static struct auth_ops *
authnone_ops()
{
static struct auth_ops ops;
extern mutex_t ops_lock;
/* VARIABLES PROTECTED BY ops_lock: ops */
mutex_lock(&ops_lock);
if (ops.ah_nextverf == NULL) {
ops.ah_nextverf = authnone_verf;
ops.ah_marshal = authnone_marshal;
ops.ah_validate = authnone_validate;
ops.ah_refresh = authnone_refresh;
ops.ah_destroy = authnone_destroy;
}
mutex_unlock(&ops_lock);
return (&ops);
}

View File

@ -45,20 +45,11 @@
#include <arpa/inet.h>
#include <rpc/rpc.h>
#include <rpc/rpc_com.h>
#include <rpc/rpcb_prot.h>
#undef NIS
#include <rpcsvc/nis.h>
#include "un-namespace.h"
/*
* FreeBSD currently uses RPC 4.0, which uses portmap rather than
* rpcbind. Consequently, we need to fake up these values here.
* Luckily, the RPCB_GETTIME procedure uses only base XDR data types
* so we don't need anything besides these magic numbers.
*/
#define RPCBPROG (u_long)100000
#define RPCBVERS (u_long)3
#define RPCBPROC_GETTIME (u_long)6
#ifdef TESTING
#define msg(x) printf("ERROR: %s\n", x)
/* #define msg(x) syslog(LOG_ERR, "%s", x) */

View File

@ -1,3 +1,5 @@
/* $NetBSD: auth_unix.c,v 1.18 2000/07/06 03:03:30 christos Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -27,10 +29,11 @@
* Mountain View, California 94043
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC";*/
static char *rcsid = "$FreeBSD$";
static char *sccsid = "@(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro";
static char *sccsid = "@(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC";
#endif
/*
@ -45,33 +48,31 @@ static char *rcsid = "$FreeBSD$";
*
*/
#include "reentrant.h"
#include "namespace.h"
#include <sys/param.h>
#include <assert.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/param.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
#include <rpc/auth_unix.h>
#include "un-namespace.h"
/*
* Unix authenticator operations vector
*/
static void authunix_nextverf();
static bool_t authunix_marshal();
static bool_t authunix_validate();
static bool_t authunix_refresh();
static void authunix_destroy();
static struct auth_ops auth_unix_ops = {
authunix_nextverf,
authunix_marshal,
authunix_validate,
authunix_refresh,
authunix_destroy
};
/* auth_unix.c */
static void authunix_nextverf (AUTH *);
static bool_t authunix_marshal (AUTH *, XDR *);
static bool_t authunix_validate (AUTH *, struct opaque_auth *);
static bool_t authunix_refresh (AUTH *, void *);
static void authunix_destroy (AUTH *);
static void marshal_new_auth (AUTH *);
static struct auth_ops *authunix_ops (void);
/*
* This struct is pointed to by the ah_private field of an auth_handle.
@ -85,21 +86,6 @@ struct audata {
};
#define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private)
static void marshal_new_auth();
/*
* This goop is here because some servers refuse to accept a
* credential with more than some number (usually 8) supplementary
* groups. Blargh!
*/
static int authunix_maxgrouplist = 0;
void
set_rpc_maxgrouplist(int num)
{
authunix_maxgrouplist = num;
}
/*
* Create a unix style authenticator.
* Returns an auth handle with the given stuff in it.
@ -109,60 +95,56 @@ authunix_create(machname, uid, gid, len, aup_gids)
char *machname;
int uid;
int gid;
register int len;
int len;
int *aup_gids;
{
struct authunix_parms aup;
char mymem[MAX_AUTH_BYTES];
struct timeval now;
XDR xdrs;
register AUTH *auth;
register struct audata *au;
AUTH *auth;
struct audata *au;
/*
* Allocate and set up auth handle
*/
auth = (AUTH *)mem_alloc(sizeof(*auth));
au = NULL;
auth = mem_alloc(sizeof(*auth));
#ifndef _KERNEL
if (auth == NULL) {
(void)fprintf(stderr, "authunix_create: out of memory\n");
return (NULL);
warnx("authunix_create: out of memory");
goto cleanup_authunix_create;
}
#endif
au = (struct audata *)mem_alloc(sizeof(*au));
au = mem_alloc(sizeof(*au));
#ifndef _KERNEL
if (au == NULL) {
(void)fprintf(stderr, "authunix_create: out of memory\n");
return (NULL);
warnx("authunix_create: out of memory");
goto cleanup_authunix_create;
}
#endif
auth->ah_ops = &auth_unix_ops;
auth->ah_ops = authunix_ops();
auth->ah_private = (caddr_t)au;
auth->ah_verf = au->au_shcred = _null_auth;
au->au_shfaults = 0;
au->au_origcred.oa_base = NULL;
/*
* fill in param struct from the given params
*/
(void)gettimeofday(&now, (struct timezone *)0);
(void)gettimeofday(&now, NULL);
aup.aup_time = now.tv_sec;
aup.aup_machname = machname;
aup.aup_uid = uid;
aup.aup_gid = gid;
/* GW: continuation of max group list hack */
if(authunix_maxgrouplist != 0) {
aup.aup_len = ((len < authunix_maxgrouplist) ? len
: authunix_maxgrouplist);
} else {
aup.aup_len = (u_int)len;
}
aup.aup_len = (u_int)len;
aup.aup_gids = aup_gids;
/*
* Serialize the parameters into origcred
*/
xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE);
if (! xdr_authunix_parms(&xdrs, &aup))
if (! xdr_authunix_parms(&xdrs, &aup))
abort();
au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs);
au->au_origcred.oa_flavor = AUTH_UNIX;
@ -170,11 +152,11 @@ authunix_create(machname, uid, gid, len, aup_gids)
au->au_origcred.oa_base = mem_alloc((u_int) len);
#else
if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) {
(void)fprintf(stderr, "authunix_create: out of memory\n");
return (NULL);
warnx("authunix_create: out of memory");
goto cleanup_authunix_create;
}
#endif
memcpy(au->au_origcred.oa_base, mymem, (u_int)len);
memmove(au->au_origcred.oa_base, mymem, (size_t)len);
/*
* set auth handle to reflect new cred.
@ -182,6 +164,17 @@ authunix_create(machname, uid, gid, len, aup_gids)
auth->ah_cred = au->au_origcred;
marshal_new_auth(auth);
return (auth);
#ifndef _KERNEL
cleanup_authunix_create:
if (auth)
mem_free(auth, sizeof(*auth));
if (au) {
if (au->au_origcred.oa_base)
mem_free(au->au_origcred.oa_base, (u_int)len);
mem_free(au, sizeof(*au));
}
return (NULL);
#endif
}
/*
@ -191,32 +184,29 @@ authunix_create(machname, uid, gid, len, aup_gids)
AUTH *
authunix_create_default()
{
register int len;
char machname[MAX_MACHINE_NAME + 1];
register int uid;
register int gid;
int gids[NGRPS];
int i;
gid_t real_gids[NGROUPS];
int len;
char machname[MAXHOSTNAMELEN + 1];
uid_t uid;
gid_t gid;
gid_t gids[NGRPS];
if (gethostname(machname, MAX_MACHINE_NAME) == -1)
if (gethostname(machname, sizeof machname) == -1)
abort();
machname[MAX_MACHINE_NAME] = 0;
uid = (int)geteuid();
gid = (int)getegid();
if ((len = getgroups(NGROUPS, real_gids)) < 0)
machname[sizeof(machname) - 1] = 0;
uid = geteuid();
gid = getegid();
if ((len = getgroups(NGRPS, gids)) < 0)
abort();
if(len > NGRPS) len = NGRPS; /* GW: turn `gid_t's into `int's */
for(i = 0; i < len; i++) {
gids[i] = (int)real_gids[i];
}
return (authunix_create(machname, uid, gid, len, gids));
/* XXX: interface problem; those should all have been unsigned */
return (authunix_create(machname, (int)uid, (int)gid, len,
(int *)gids));
}
/*
* authunix operations
*/
/* ARGSUSED */
static void
authunix_nextverf(auth)
AUTH *auth;
@ -229,22 +219,30 @@ authunix_marshal(auth, xdrs)
AUTH *auth;
XDR *xdrs;
{
register struct audata *au = AUTH_PRIVATE(auth);
struct audata *au;
assert(auth != NULL);
assert(xdrs != NULL);
au = AUTH_PRIVATE(auth);
return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos));
}
static bool_t
authunix_validate(auth, verf)
register AUTH *auth;
struct opaque_auth verf;
AUTH *auth;
struct opaque_auth *verf;
{
register struct audata *au;
struct audata *au;
XDR xdrs;
if (verf.oa_flavor == AUTH_SHORT) {
assert(auth != NULL);
assert(verf != NULL);
if (verf->oa_flavor == AUTH_SHORT) {
au = AUTH_PRIVATE(auth);
xdrmem_create(&xdrs, verf.oa_base, verf.oa_length, XDR_DECODE);
xdrmem_create(&xdrs, verf->oa_base, verf->oa_length,
XDR_DECODE);
if (au->au_shcred.oa_base != NULL) {
mem_free(au->au_shcred.oa_base,
@ -265,14 +263,15 @@ authunix_validate(auth, verf)
}
static bool_t
authunix_refresh(auth)
register AUTH *auth;
authunix_refresh(AUTH *auth, void *dummy)
{
register struct audata *au = AUTH_PRIVATE(auth);
struct audata *au = AUTH_PRIVATE(auth);
struct authunix_parms aup;
struct timeval now;
XDR xdrs;
register int stat;
int stat;
assert(auth != NULL);
if (auth->ah_cred.oa_base == au->au_origcred.oa_base) {
/* there is no hope. Punt */
@ -282,7 +281,7 @@ authunix_refresh(auth)
/* first deserialize the creds back into a struct authunix_parms */
aup.aup_machname = NULL;
aup.aup_gids = (int *)NULL;
aup.aup_gids = NULL;
xdrmem_create(&xdrs, au->au_origcred.oa_base,
au->au_origcred.oa_length, XDR_DECODE);
stat = xdr_authunix_parms(&xdrs, &aup);
@ -290,7 +289,7 @@ authunix_refresh(auth)
goto done;
/* update the time and serialize in place */
(void)gettimeofday(&now, (struct timezone *)0);
(void)gettimeofday(&now, NULL);
aup.aup_time = now.tv_sec;
xdrs.x_op = XDR_ENCODE;
XDR_SETPOS(&xdrs, 0);
@ -309,10 +308,13 @@ authunix_refresh(auth)
static void
authunix_destroy(auth)
register AUTH *auth;
AUTH *auth;
{
register struct audata *au = AUTH_PRIVATE(auth);
struct audata *au;
assert(auth != NULL);
au = AUTH_PRIVATE(auth);
mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length);
if (au->au_shcred.oa_base != NULL)
@ -323,7 +325,7 @@ authunix_destroy(auth)
if (auth->ah_verf.oa_base != NULL)
mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length);
mem_free((caddr_t)auth, sizeof(*auth));
mem_free(auth, sizeof(*auth));
}
/*
@ -332,18 +334,40 @@ authunix_destroy(auth)
*/
static void
marshal_new_auth(auth)
register AUTH *auth;
AUTH *auth;
{
XDR xdr_stream;
register XDR *xdrs = &xdr_stream;
register struct audata *au = AUTH_PRIVATE(auth);
XDR xdr_stream;
XDR *xdrs = &xdr_stream;
struct audata *au;
assert(auth != NULL);
au = AUTH_PRIVATE(auth);
xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE);
if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) ||
(! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) {
perror("auth_none.c - Fatal marshalling problem");
} else {
(! xdr_opaque_auth(xdrs, &(auth->ah_verf))))
warnx("auth_none.c - Fatal marshalling problem");
else
au->au_mpos = XDR_GETPOS(xdrs);
}
XDR_DESTROY(xdrs);
}
static struct auth_ops *
authunix_ops()
{
static struct auth_ops ops;
extern mutex_t ops_lock;
/* VARIABLES PROTECTED BY ops_lock: ops */
mutex_lock(&ops_lock);
if (ops.ah_nextverf == NULL) {
ops.ah_nextverf = authunix_nextverf;
ops.ah_marshal = authunix_marshal;
ops.ah_validate = authunix_validate;
ops.ah_refresh = authunix_refresh;
ops.ah_destroy = authunix_destroy;
}
mutex_unlock(&ops_lock);
return (&ops);
}

View File

@ -1,6 +1,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)authdes_prot.c 2.1 88/07/29 4.0 RPCSRC; from 1.6 88/02/08 SMI";
#endif
/* $FreeBSD$ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -30,17 +31,19 @@ static char sccsid[] = "@(#)authdes_prot.c 2.1 88/07/29 4.0 RPCSRC; from 1.6 88
* Mountain View, California 94043
*/
/*
* Copyright (c) 1988 by Sun Microsystems, Inc.
* Copyright (c) 1986-1991 by Sun Microsystems Inc.
*/
/*
* authdes_prot.c, XDR routines for DES authentication
*/
#include "namespace.h"
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
#include <rpc/auth_des.h>
#include "un-namespace.h"
#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE)
@ -55,12 +58,16 @@ xdr_authdes_cred(xdrs, cred)
ATTEMPT(xdr_enum(xdrs, (enum_t *)&cred->adc_namekind));
switch (cred->adc_namekind) {
case ADN_FULLNAME:
ATTEMPT(xdr_string(xdrs, &cred->adc_fullname.name, MAXNETNAMELEN));
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_fullname.key, sizeof(des_block)));
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_fullname.window, sizeof(cred->adc_fullname.window)));
ATTEMPT(xdr_string(xdrs, &cred->adc_fullname.name,
MAXNETNAMELEN));
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_fullname.key,
sizeof(des_block)));
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_fullname.window,
sizeof(cred->adc_fullname.window)));
return (TRUE);
case ADN_NICKNAME:
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_nickname, sizeof(cred->adc_nickname)));
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_nickname,
sizeof(cred->adc_nickname)));
return (TRUE);
default:
return (FALSE);
@ -76,7 +83,9 @@ xdr_authdes_verf(xdrs, verf)
/*
* Unrolled xdr
*/
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&verf->adv_xtimestamp, sizeof(des_block)));
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&verf->adv_int_u, sizeof(verf->adv_int_u)));
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&verf->adv_xtimestamp,
sizeof(des_block)));
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&verf->adv_int_u,
sizeof(verf->adv_int_u)));
return (TRUE);
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: authunix_prot.c,v 1.12 2000/01/22 22:19:17 mycroft Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -27,10 +29,11 @@
* Mountain View, California 94043
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)authunix_prot.c 1.15 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)authunix_prot.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *rcsid = "$FreeBSD$";
static char *sccsid = "@(#)authunix_prot.c 1.15 87/08/11 Copyr 1984 Sun Micro";
static char *sccsid = "@(#)authunix_prot.c 2.1 88/07/29 4.0 RPCSRC";
#endif
/*
@ -40,29 +43,34 @@ static char *rcsid = "$FreeBSD$";
* Copyright (C) 1984, Sun Microsystems, Inc.
*/
#include "namespace.h"
#include <assert.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
#include <rpc/auth_unix.h>
#include "un-namespace.h"
/*
* XDR for unix authentication parameters.
*/
bool_t
xdr_authunix_parms(xdrs, p)
register XDR *xdrs;
register struct authunix_parms *p;
XDR *xdrs;
struct authunix_parms *p;
{
assert(xdrs != NULL);
assert(p != NULL);
if (xdr_u_long(xdrs, &(p->aup_time))
&& xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME)
&& xdr_int(xdrs, &(p->aup_uid))
&& xdr_int(xdrs, &(p->aup_gid))
&& xdr_array(xdrs, (caddr_t *)&(p->aup_gids),
&(p->aup_len), NGRPS, sizeof(int), xdr_int) ) {
&(p->aup_len), NGRPS, sizeof(int), (xdrproc_t)xdr_int) ) {
return (TRUE);
}
return (FALSE);
}

View File

@ -1,14 +1,18 @@
.\" @(#)bindresvport.3n 2.2 88/08/02 4.0 RPCSRC; from 1.7 88/03/14 SMI
.\" $NetBSD: bindresvport.3,v 1.8 2000/07/05 15:45:33 msaitoh Exp $
.\" $FreeBSD$
.\"
.Dd January 27, 2000
.Dd November 22, 1987
.Dt BINDRESVPORT 3
.Os
.Sh NAME
.Nm bindresvport ,
.Nm bindresvport_sa
.Nd bind a socket to a privileged IP port
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.Fd #include <sys/types.h>
.Fd #include <rpc/rpc.h>
.Ft int
.Fn bindresvport "int sd" "struct sockaddr_in *sin"
@ -23,26 +27,39 @@ are used to bind a socket descriptor to a privileged
port, that is, a
port number in the range 0-1023.
.Pp
If
.Fa sin
is a pointer to a
.Ft "struct sockaddr_in"
then the appropriate fields in the structure should be defined.
Note that
.Fa sin->sin_family
must be initialized to the address family of the socket, passed by
.Fa sd .
If
.Fa sin->sin_port
is
.Sq 0
then an anonymous port (in the range 600-1023) will be
chosen, and if
.Xr bind 2
is successful, the
.Fa sin->sin_port
will be updated to contain the allocated port.
.Pp
If
.Fa sin
is the
.Dv NULL
pointer,
an anonymous port will be allocated (as above).
However, there is no way for
.Fn bindresvport
to return the allocated port in this case.
.Pp
Only root can bind to a privileged port; this call will fail for any
other users.
.Pp
When
.Va sin
is not null,
.Va sin->sin_family
must be initialized to the address family of the socket, passed by
.Va sd .
If the value of sin->sin_port is non-zero
.Fn bindresvport
will attempt to use that specific port. If it fails, it chooses another
privileged port automatically.
.Pp
It is legal to pass null pointer to
.Va sin .
In this case, the caller cannot get the port number
.Fn bindresvport
has picked.
.Pp
Function prototype of
.Fn bindresvport
is biased to
@ -57,50 +74,24 @@ sockets as well as
.Dv AF_INET
sockets.
.Sh RETURN VALUES
.Fn bindresvport
and
.Fn bindresvport_sa
return 0 if they are successful, otherwise \-1 is returned and
.Va errno
set to reflect the cause of the error.
.Rv -std bindresvport
.Sh ERRORS
The
.Fn bindresvport
and
.Fn bindresvport_sa
functions fail if:
.Bl -tag -width Er
.It Bq Er EBADF
.Fa sd
is not a valid descriptor.
.It Bq Er ENOTSOCK
.Fa sd
is not a socket.
.It Bq Er EADDRNOTAVAIL
The specified address is not available from the local machine.
.It Bq Er EADDRINUSE
The specified address is already in use.
.It Bq Er EINVAL
The socket is already bound to an address,
or the socket family and the family of specified address mismatch.
.It Bq Er EACCES
The requested address is protected, and the current user
has inadequate permission to access it.
.It Bq Er EFAULT
The
.Fa name
parameter is not in a valid part of the user
address space.
.It Bq Er ENOBUFS
Insufficient resources were available in the system
to perform the operation.
.It Bq Er EPFNOSUPPORT
The protocol family has not been configured into the
system, no implementation for it exists,
or address family did not match between arguments.
If second argument was supplied,
and address family did not match between arguments.
.El
.Sh "SEE ALSO"
.Pp
.Fn bindresvport
may also fail and set
.Va errno
for any of the errors specified for the calls
.Xr bind 2 ,
.Xr socket 2 ,
.Xr rresvport 3 ,
.Xr rresvport_af 3
.Xr getsockopt 2 ,
or
.Xr setsockopt 2 .
.Sh SEE ALSO
.Xr bind 2 ,
.Xr getsockopt 2 ,
.Xr setsockopt 2 ,
.Xr ip 4

View File

@ -1,3 +1,5 @@
/* $NetBSD: bindresvport.c,v 1.19 2000/07/06 03:03:59 christos Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -27,6 +29,7 @@
* Mountain View, California 94043
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)bindresvport.c 1.8 88/02/08 SMI";*/
/*static char *sccsid = "from: @(#)bindresvport.c 2.2 88/07/29 4.0 RPCSRC";*/
@ -42,10 +45,16 @@ static char *rcsid = "$FreeBSD$";
#include "namespace.h"
#include <sys/types.h>
#include <sys/errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <rpc/rpc.h>
#include <string.h>
#include "un-namespace.h"
@ -61,7 +70,7 @@ bindresvport(sd, sin)
}
/*
* Bind a socket to a privileged port for whatever protocol.
* Bind a socket to a privileged IP port
*/
int
bindresvport_sa(sd, sa)
@ -71,10 +80,12 @@ bindresvport_sa(sd, sa)
int old, error, af;
struct sockaddr_storage myaddr;
struct sockaddr_in *sin;
#ifdef INET6
struct sockaddr_in6 *sin6;
#endif
int proto, portrange, portlow;
u_int16_t port;
int salen;
u_int16_t *portp;
socklen_t salen;
if (sa == NULL) {
salen = sizeof(myaddr);
@ -84,33 +95,38 @@ bindresvport_sa(sd, sa)
return -1; /* errno is correctly set */
af = sa->sa_family;
memset(&myaddr, 0, salen);
memset(sa, 0, salen);
} else
af = sa->sa_family;
if (af == AF_INET) {
switch (af) {
case AF_INET:
proto = IPPROTO_IP;
portrange = IP_PORTRANGE;
portlow = IP_PORTRANGE_LOW;
sin = (struct sockaddr_in *)sa;
salen = sizeof(struct sockaddr_in);
port = sin->sin_port;
} else if (af == AF_INET6) {
portp = &sin->sin_port;
break;
#ifdef INET6
case AF_INET6:
proto = IPPROTO_IPV6;
portrange = IPV6_PORTRANGE;
portlow = IPV6_PORTRANGE_LOW;
sin6 = (struct sockaddr_in6 *)sa;
salen = sizeof(struct sockaddr_in6);
port = sin6->sin6_port;
} else {
portp = &sin6->sin6_port;
break;
#endif
default:
errno = EPFNOSUPPORT;
return (-1);
}
sa->sa_family = af;
sa->sa_len = salen;
if (port == 0) {
int oldlen = sizeof(old);
if (*portp == 0) {
socklen_t oldlen = sizeof(old);
error = _getsockopt(sd, proto, portrange, &old, &oldlen);
if (error < 0)
@ -124,10 +140,10 @@ bindresvport_sa(sd, sa)
error = _bind(sd, sa, salen);
if (port == 0) {
if (*portp == 0) {
int saved_errno = errno;
if (error) {
if (error < 0) {
if (_setsockopt(sd, proto, portrange, &old,
sizeof(old)) < 0)
errno = saved_errno;
@ -135,7 +151,7 @@ bindresvport_sa(sd, sa)
}
if (sa != (struct sockaddr *)&myaddr) {
/* Hmm, what did the kernel assign... */
/* Hmm, what did the kernel assign? */
if (_getsockname(sd, sa, &salen) < 0)
errno = saved_errno;
return (error);

667
lib/libc/rpc/clnt_bcast.c Normal file
View File

@ -0,0 +1,667 @@
/* $NetBSD: clnt_bcast.c,v 1.3 2000/07/06 03:05:20 christos Exp $ */
/* $FreeBSD$ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1986-1991 by Sun Microsystems Inc.
*/
/* #ident "@(#)clnt_bcast.c 1.18 94/05/03 SMI" */
#if !defined(lint) && defined(SCCSIDS)
static char sccsid[] = "@(#)clnt_bcast.c 1.15 89/04/21 Copyr 1988 Sun Micro";
#endif
/*
* clnt_bcast.c
* Client interface to broadcast service.
*
* Copyright (C) 1988, Sun Microsystems, Inc.
*
* The following is kludged-up support for simple rpc broadcasts.
* Someday a large, complicated system will replace these routines.
*/
#include "namespace.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/queue.h>
#include <net/if.h>
#include <netinet/in.h>
#include <ifaddrs.h>
#include <sys/poll.h>
#include <rpc/rpc.h>
#ifdef PORTMAP
#include <rpc/pmap_prot.h>
#include <rpc/pmap_clnt.h>
#include <rpc/pmap_rmt.h>
#endif /* PORTMAP */
#include <rpc/nettype.h>
#include <arpa/inet.h>
#ifdef RPC_DEBUG
#include <stdio.h>
#endif
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <err.h>
#include <string.h>
#include "un-namespace.h"
#include "rpc_com.h"
#define MAXBCAST 20 /* Max no of broadcasting transports */
#define INITTIME 4000 /* Time to wait initially */
#define WAITTIME 8000 /* Maximum time to wait */
/*
* If nettype is NULL, it broadcasts on all the available
* datagram_n transports. May potentially lead to broadacst storms
* and hence should be used with caution, care and courage.
*
* The current parameter xdr packet size is limited by the max tsdu
* size of the transport. If the max tsdu size of any transport is
* smaller than the parameter xdr packet, then broadcast is not
* sent on that transport.
*
* Also, the packet size should be less the packet size of
* the data link layer (for ethernet it is 1400 bytes). There is
* no easy way to find out the max size of the data link layer and
* we are assuming that the args would be smaller than that.
*
* The result size has to be smaller than the transport tsdu size.
*
* If PORTMAP has been defined, we send two packets for UDP, one for
* rpcbind and one for portmap. For those machines which support
* both rpcbind and portmap, it will cause them to reply twice, and
* also here it will get two responses ... inefficient and clumsy.
*/
struct broadif {
int index;
struct sockaddr_storage broadaddr;
TAILQ_ENTRY(broadif) link;
};
typedef TAILQ_HEAD(, broadif) broadlist_t;
int __rpc_getbroadifs __P((int, int, int, broadlist_t *));
void __rpc_freebroadifs __P((broadlist_t *));
int __rpc_broadenable __P((int, int, struct broadif *));
int __rpc_lowvers = 0;
int
__rpc_getbroadifs(int af, int proto, int socktype, broadlist_t *list)
{
int count = 0;
struct broadif *bip;
struct ifaddrs *ifap, *ifp;
#ifdef INET6
struct sockaddr_in6 *sin6;
#endif
struct sockaddr_in *sin;
struct addrinfo hints, *res;
if (getifaddrs(&ifp) < 0)
return 0;
memset(&hints, 0, sizeof hints);
hints.ai_family = af;
hints.ai_protocol = proto;
hints.ai_socktype = socktype;
if (getaddrinfo(NULL, "sunrpc", &hints, &res) != 0)
return 0;
for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
if (ifap->ifa_addr->sa_family != af ||
!(ifap->ifa_flags & IFF_UP))
continue;
#ifdef INET6
if ((af == AF_INET6 && !(ifap->ifa_flags & IFF_MULTICAST)) ||
!(ifap->ifa_flags & IFF_BROADCAST))
continue;
#endif
bip = (struct broadif *)malloc(sizeof *bip);
if (bip == NULL)
break;
bip->index = if_nametoindex(ifap->ifa_name);
#ifdef INET6
if (af != AF_INET6 && (ifap->ifa_flags & IFF_BROADCAST)) {
#else
if (ifap->ifa_flags & IFF_BROADCAST) {
#endif
memcpy(&bip->broadaddr, ifap->ifa_broadaddr,
(size_t)ifap->ifa_broadaddr->sa_len);
sin = (struct sockaddr_in *)(void *)&bip->broadaddr;
sin->sin_port =
((struct sockaddr_in *)
(void *)res->ai_addr)->sin_port;
#ifdef INET6
} else if (af == AF_INET6) {
sin6 = (struct sockaddr_in6 *)(void *)&bip->broadaddr;
inet_pton(af, RPCB_MULTICAST_ADDR, &sin6->sin6_addr);
sin6->sin6_family = af;
sin6->sin6_len = sizeof *sin6;
sin6->sin6_port =
((struct sockaddr_in6 *)
(void *)res->ai_addr)->sin6_port;
sin6->sin6_scope_id = bip->index;
#endif
}
TAILQ_INSERT_TAIL(list, bip, link);
count++;
}
freeifaddrs(ifp);
freeaddrinfo(res);
return count;
}
void
__rpc_freebroadifs(broadlist_t *list)
{
struct broadif *bip, *next;
bip = TAILQ_FIRST(list);
while (bip != NULL) {
next = TAILQ_NEXT(bip, link);
free(bip);
bip = next;
}
}
int
/*ARGSUSED*/
__rpc_broadenable(int af, int s, struct broadif *bip)
{
int o = 1;
#if 0
if (af == AF_INET6) {
fprintf(stderr, "set v6 multicast if to %d\n", bip->index);
if (_setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, &bip->index,
sizeof bip->index) < 0)
return -1;
} else
#endif
if (_setsockopt(s, SOL_SOCKET, SO_BROADCAST, &o, sizeof o) < 0)
return -1;
return 0;
}
enum clnt_stat
rpc_broadcast_exp(prog, vers, proc, xargs, argsp, xresults, resultsp,
eachresult, inittime, waittime, nettype)
rpcprog_t prog; /* program number */
rpcvers_t vers; /* version number */
rpcproc_t proc; /* procedure number */
xdrproc_t xargs; /* xdr routine for args */
caddr_t argsp; /* pointer to args */
xdrproc_t xresults; /* xdr routine for results */
caddr_t resultsp; /* pointer to results */
resultproc_t eachresult; /* call with each result obtained */
int inittime; /* how long to wait initially */
int waittime; /* maximum time to wait */
const char *nettype; /* transport type */
{
enum clnt_stat stat = RPC_SUCCESS; /* Return status */
XDR xdr_stream; /* XDR stream */
XDR *xdrs = &xdr_stream;
struct rpc_msg msg; /* RPC message */
struct timeval t;
char *outbuf = NULL; /* Broadcast msg buffer */
char *inbuf = NULL; /* Reply buf */
int inlen;
u_int maxbufsize = 0;
AUTH *sys_auth = authunix_create_default();
int i;
void *handle;
char uaddress[1024]; /* A self imposed limit */
char *uaddrp = uaddress;
int pmap_reply_flag; /* reply recvd from PORTMAP */
/* An array of all the suitable broadcast transports */
struct {
int fd; /* File descriptor */
int af;
int proto;
struct netconfig *nconf; /* Netconfig structure */
u_int asize; /* Size of the addr buf */
u_int dsize; /* Size of the data buf */
struct sockaddr_storage raddr; /* Remote address */
broadlist_t nal;
} fdlist[MAXBCAST];
struct pollfd pfd[MAXBCAST];
size_t fdlistno = 0;
struct r_rpcb_rmtcallargs barg; /* Remote arguments */
struct r_rpcb_rmtcallres bres; /* Remote results */
size_t outlen, outlen_pmap;
struct netconfig *nconf;
int msec;
int pollretval;
int fds_found;
#ifdef PORTMAP
u_long port; /* Remote port number */
int pmap_flag = 0; /* UDP exists ? */
char *outbuf_pmap = NULL;
struct rmtcallargs barg_pmap; /* Remote arguments */
struct rmtcallres bres_pmap; /* Remote results */
u_int udpbufsz = 0;
#endif /* PORTMAP */
if (sys_auth == NULL) {
return (RPC_SYSTEMERROR);
}
/*
* initialization: create a fd, a broadcast address, and send the
* request on the broadcast transport.
* Listen on all of them and on replies, call the user supplied
* function.
*/
if (nettype == NULL)
nettype = "datagram_n";
if ((handle = __rpc_setconf(nettype)) == NULL) {
return (RPC_UNKNOWNPROTO);
}
while ((nconf = __rpc_getconf(handle)) != NULL) {
int fd;
struct __rpc_sockinfo si;
if (nconf->nc_semantics != NC_TPI_CLTS)
continue;
if (fdlistno >= MAXBCAST)
break; /* No more slots available */
if (!__rpc_nconf2sockinfo(nconf, &si))
continue;
TAILQ_INIT(&fdlist[fdlistno].nal);
if (__rpc_getbroadifs(si.si_af, si.si_proto, si.si_socktype,
&fdlist[fdlistno].nal) == 0)
continue;
fd = _socket(si.si_af, si.si_socktype, si.si_proto);
if (fd < 0) {
stat = RPC_CANTSEND;
continue;
}
fdlist[fdlistno].af = si.si_af;
fdlist[fdlistno].proto = si.si_proto;
fdlist[fdlistno].fd = fd;
fdlist[fdlistno].nconf = nconf;
fdlist[fdlistno].asize = __rpc_get_a_size(si.si_af);
pfd[fdlistno].events = POLLIN | POLLPRI |
POLLRDNORM | POLLRDBAND;
pfd[fdlistno].fd = fdlist[fdlistno].fd = fd;
fdlist[fdlistno].dsize = __rpc_get_t_size(si.si_af, si.si_proto,
0);
if (maxbufsize <= fdlist[fdlistno].dsize)
maxbufsize = fdlist[fdlistno].dsize;
#ifdef PORTMAP
if (si.si_af == AF_INET && si.si_proto == IPPROTO_UDP) {
udpbufsz = fdlist[fdlistno].dsize;
if ((outbuf_pmap = malloc(udpbufsz)) == NULL) {
_close(fd);
stat = RPC_SYSTEMERROR;
goto done_broad;
}
pmap_flag = 1;
}
#endif /* PORTMAP */
fdlistno++;
}
if (fdlistno == 0) {
if (stat == RPC_SUCCESS)
stat = RPC_UNKNOWNPROTO;
goto done_broad;
}
if (maxbufsize == 0) {
if (stat == RPC_SUCCESS)
stat = RPC_CANTSEND;
goto done_broad;
}
inbuf = malloc(maxbufsize);
outbuf = malloc(maxbufsize);
if ((inbuf == NULL) || (outbuf == NULL)) {
stat = RPC_SYSTEMERROR;
goto done_broad;
}
/* Serialize all the arguments which have to be sent */
(void) gettimeofday(&t, NULL);
msg.rm_xid = __RPC_GETXID(&t);
msg.rm_direction = CALL;
msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
msg.rm_call.cb_prog = RPCBPROG;
msg.rm_call.cb_vers = RPCBVERS;
msg.rm_call.cb_proc = RPCBPROC_CALLIT;
barg.prog = prog;
barg.vers = vers;
barg.proc = proc;
barg.args.args_val = argsp;
barg.xdr_args = xargs;
bres.addr = uaddrp;
bres.results.results_val = resultsp;
bres.xdr_res = xresults;
msg.rm_call.cb_cred = sys_auth->ah_cred;
msg.rm_call.cb_verf = sys_auth->ah_verf;
xdrmem_create(xdrs, outbuf, maxbufsize, XDR_ENCODE);
if ((!xdr_callmsg(xdrs, &msg)) ||
(!xdr_rpcb_rmtcallargs(xdrs,
(struct rpcb_rmtcallargs *)(void *)&barg))) {
stat = RPC_CANTENCODEARGS;
goto done_broad;
}
outlen = xdr_getpos(xdrs);
xdr_destroy(xdrs);
#ifdef PORTMAP
/* Prepare the packet for version 2 PORTMAP */
if (pmap_flag) {
msg.rm_xid++; /* One way to distinguish */
msg.rm_call.cb_prog = PMAPPROG;
msg.rm_call.cb_vers = PMAPVERS;
msg.rm_call.cb_proc = PMAPPROC_CALLIT;
barg_pmap.prog = prog;
barg_pmap.vers = vers;
barg_pmap.proc = proc;
barg_pmap.args_ptr = argsp;
barg_pmap.xdr_args = xargs;
bres_pmap.port_ptr = &port;
bres_pmap.xdr_results = xresults;
bres_pmap.results_ptr = resultsp;
xdrmem_create(xdrs, outbuf_pmap, udpbufsz, XDR_ENCODE);
if ((! xdr_callmsg(xdrs, &msg)) ||
(! xdr_rmtcall_args(xdrs, &barg_pmap))) {
stat = RPC_CANTENCODEARGS;
goto done_broad;
}
outlen_pmap = xdr_getpos(xdrs);
xdr_destroy(xdrs);
}
#endif PORTMAP
/*
* Basic loop: broadcast the packets to transports which
* support data packets of size such that one can encode
* all the arguments.
* Wait a while for response(s).
* The response timeout grows larger per iteration.
*/
for (msec = inittime; msec <= waittime; msec += msec) {
struct broadif *bip;
/* Broadcast all the packets now */
for (i = 0; i < fdlistno; i++) {
if (fdlist[i].dsize < outlen) {
stat = RPC_CANTSEND;
continue;
}
for (bip = TAILQ_FIRST(&fdlist[i].nal); bip != NULL;
bip = TAILQ_NEXT(bip, link)) {
void *addr;
addr = &bip->broadaddr;
__rpc_broadenable(fdlist[i].af, fdlist[i].fd,
bip);
/*
* Only use version 3 if lowvers is not set
*/
if (!__rpc_lowvers)
if (_sendto(fdlist[i].fd, outbuf,
outlen, 0, (struct sockaddr*)addr,
(size_t)fdlist[i].asize) !=
outlen) {
#ifdef RPC_DEBUG
perror("sendto");
#endif
warnx("clnt_bcast: cannot send"
"broadcast packet");
stat = RPC_CANTSEND;
continue;
};
#ifdef RPC_DEBUG
if (!__rpc_lowvers)
fprintf(stderr, "Broadcast packet sent "
"for %s\n",
fdlist[i].nconf->nc_netid);
#endif
#ifdef PORTMAP
/*
* Send the version 2 packet also
* for UDP/IP
*/
if (fdlist[i].proto == IPPROTO_UDP) {
if (_sendto(fdlist[i].fd, outbuf_pmap,
outlen_pmap, 0, addr,
(size_t)fdlist[i].asize) !=
outlen_pmap) {
warnx("clnt_bcast: "
"Cannot send broadcast packet");
stat = RPC_CANTSEND;
continue;
}
}
#ifdef RPC_DEBUG
fprintf(stderr, "PMAP Broadcast packet "
"sent for %s\n",
fdlist[i].nconf->nc_netid);
#endif
#endif /* PORTMAP */
}
/* End for sending all packets on this transport */
} /* End for sending on all transports */
if (eachresult == NULL) {
stat = RPC_SUCCESS;
goto done_broad;
}
/*
* Get all the replies from these broadcast requests
*/
recv_again:
switch (pollretval = _poll(pfd, fdlistno, msec)) {
case 0: /* timed out */
stat = RPC_TIMEDOUT;
continue;
case -1: /* some kind of error - we ignore it */
goto recv_again;
} /* end of poll results switch */
for (i = fds_found = 0;
i < fdlistno && fds_found < pollretval; i++) {
bool_t done = FALSE;
if (pfd[i].revents == 0)
continue;
else if (pfd[i].revents & POLLNVAL) {
/*
* Something bad has happened to this descri-
* ptor. We can cause _poll() to ignore
* it simply by using a negative fd. We do that
* rather than compacting the pfd[] and fdlist[]
* arrays.
*/
pfd[i].fd = -1;
fds_found++;
continue;
} else
fds_found++;
#ifdef RPC_DEBUG
fprintf(stderr, "response for %s\n",
fdlist[i].nconf->nc_netid);
#endif
try_again:
inlen = _recvfrom(fdlist[i].fd, inbuf, fdlist[i].dsize,
0, (struct sockaddr *)(void *)&fdlist[i].raddr,
&fdlist[i].asize);
if (inlen < 0) {
if (errno == EINTR)
goto try_again;
warnx("clnt_bcast: Cannot receive reply to "
"broadcast");
stat = RPC_CANTRECV;
continue;
}
if (inlen < sizeof (u_int32_t))
continue; /* Drop that and go ahead */
/*
* see if reply transaction id matches sent id.
* If so, decode the results. If return id is xid + 1
* it was a PORTMAP reply
*/
if (*((u_int32_t *)(void *)(inbuf)) ==
*((u_int32_t *)(void *)(outbuf))) {
pmap_reply_flag = 0;
msg.acpted_rply.ar_verf = _null_auth;
msg.acpted_rply.ar_results.where =
(caddr_t)(void *)&bres;
msg.acpted_rply.ar_results.proc =
(xdrproc_t)xdr_rpcb_rmtcallres;
#ifdef PORTMAP
} else if (pmap_flag &&
*((u_int32_t *)(void *)(inbuf)) ==
*((u_int32_t *)(void *)(outbuf_pmap))) {
pmap_reply_flag = 1;
msg.acpted_rply.ar_verf = _null_auth;
msg.acpted_rply.ar_results.where =
(caddr_t)(void *)&bres_pmap;
msg.acpted_rply.ar_results.proc =
(xdrproc_t)xdr_rmtcallres;
#endif /* PORTMAP */
} else
continue;
xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE);
if (xdr_replymsg(xdrs, &msg)) {
if ((msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
(msg.acpted_rply.ar_stat == SUCCESS)) {
struct netbuf taddr, *np;
struct sockaddr_in *sin;
#ifdef PORTMAP
if (pmap_flag && pmap_reply_flag) {
sin = (struct sockaddr_in *)
(void *)&fdlist[i].raddr;
sin->sin_port =
htons((u_short)port);
taddr.len = taddr.maxlen =
fdlist[i].raddr.ss_len;
taddr.buf = &fdlist[i].raddr;
done = (*eachresult)(resultsp,
&taddr, fdlist[i].nconf);
} else {
#endif /* PORTMAP */
#ifdef RPC_DEBUG
fprintf(stderr, "uaddr %s\n",
uaddrp);
#endif
np = uaddr2taddr(
fdlist[i].nconf, uaddrp);
done = (*eachresult)(resultsp,
np, fdlist[i].nconf);
free(np);
#ifdef PORTMAP
}
#endif /* PORTMAP */
}
/* otherwise, we just ignore the errors ... */
}
/* else some kind of deserialization problem ... */
xdrs->x_op = XDR_FREE;
msg.acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
(void) xdr_replymsg(xdrs, &msg);
(void) (*xresults)(xdrs, resultsp);
XDR_DESTROY(xdrs);
if (done) {
stat = RPC_SUCCESS;
goto done_broad;
} else {
goto recv_again;
}
} /* The recv for loop */
} /* The giant for loop */
done_broad:
if (inbuf)
(void) free(inbuf);
if (outbuf)
(void) free(outbuf);
#ifdef PORTMAP
if (outbuf_pmap)
(void) free(outbuf_pmap);
#endif /* PORTMAP */
for (i = 0; i < fdlistno; i++) {
(void)_close(fdlist[i].fd);
__rpc_freebroadifs(&fdlist[i].nal);
}
AUTH_DESTROY(sys_auth);
(void) __rpc_endconf(handle);
return (stat);
}
enum clnt_stat
rpc_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp,
eachresult, nettype)
rpcprog_t prog; /* program number */
rpcvers_t vers; /* version number */
rpcproc_t proc; /* procedure number */
xdrproc_t xargs; /* xdr routine for args */
caddr_t argsp; /* pointer to args */
xdrproc_t xresults; /* xdr routine for results */
caddr_t resultsp; /* pointer to results */
resultproc_t eachresult; /* call with each result obtained */
const char *nettype; /* transport type */
{
enum clnt_stat dummy;
dummy = rpc_broadcast_exp(prog, vers, proc, xargs, argsp,
xresults, resultsp, eachresult,
INITTIME, WAITTIME, nettype);
return (dummy);
}

821
lib/libc/rpc/clnt_dg.c Normal file
View File

@ -0,0 +1,821 @@
/* $NetBSD: clnt_dg.c,v 1.4 2000/07/14 08:40:41 fvdl Exp $ */
/* $FreeBSD$ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1986-1991 by Sun Microsystems Inc.
*/
/* #ident "@(#)clnt_dg.c 1.23 94/04/22 SMI" */
#if 0
#if !defined(lint) && defined(SCCSIDS)
static char sccsid[] = "@(#)clnt_dg.c 1.19 89/03/16 Copyr 1988 Sun Micro";
#endif
#endif
/*
* Implements a connectionless client side RPC.
*/
#include "reentrant.h"
#include "namespace.h"
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <rpc/rpc.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <err.h>
#include "un-namespace.h"
#include "rpc_com.h"
#define RPC_MAX_BACKOFF 30 /* seconds */
static struct clnt_ops *clnt_dg_ops __P((void));
static bool_t time_not_ok __P((struct timeval *));
static enum clnt_stat clnt_dg_call __P((CLIENT *, rpcproc_t, xdrproc_t, caddr_t,
xdrproc_t, caddr_t, struct timeval));
static void clnt_dg_geterr __P((CLIENT *, struct rpc_err *));
static bool_t clnt_dg_freeres __P((CLIENT *, xdrproc_t, caddr_t));
static void clnt_dg_abort __P((CLIENT *));
static bool_t clnt_dg_control __P((CLIENT *, u_int, char *));
static void clnt_dg_destroy __P((CLIENT *));
static int __rpc_timeval_to_msec __P((struct timeval *));
/*
* This machinery implements per-fd locks for MT-safety. It is not
* sufficient to do per-CLIENT handle locks for MT-safety because a
* user may create more than one CLIENT handle with the same fd behind
* it. Therfore, we allocate an array of flags (dg_fd_locks), protected
* by the clnt_fd_lock mutex, and an array (dg_cv) of condition variables
* similarly protected. Dg_fd_lock[fd] == 1 => a call is activte on some
* CLIENT handle created for that fd.
* The current implementation holds locks across the entire RPC and reply,
* including retransmissions. Yes, this is silly, and as soon as this
* code is proven to work, this should be the first thing fixed. One step
* at a time.
*/
static int *dg_fd_locks;
extern mutex_t clnt_fd_lock;
static cond_t *dg_cv;
#define release_fd_lock(fd, mask) { \
mutex_lock(&clnt_fd_lock); \
if (__isthreaded) \
dg_fd_locks[fd] = 0; \
mutex_unlock(&clnt_fd_lock); \
thr_sigsetmask(SIG_SETMASK, &(mask), (sigset_t *) NULL); \
cond_signal(&dg_cv[fd]); \
}
static const char mem_err_clnt_dg[] = "clnt_dg_create: out of memory";
/* VARIABLES PROTECTED BY clnt_fd_lock: dg_fd_locks, dg_cv */
/*
* Private data kept per client handle
*/
struct cu_data {
int cu_fd; /* connections fd */
bool_t cu_closeit; /* opened by library */
struct sockaddr_storage cu_raddr; /* remote address */
int cu_rlen;
struct timeval cu_wait; /* retransmit interval */
struct timeval cu_total; /* total time for the call */
struct rpc_err cu_error;
XDR cu_outxdrs;
u_int cu_xdrpos;
u_int cu_sendsz; /* send size */
char *cu_outbuf;
u_int cu_recvsz; /* recv size */
struct pollfd pfdp;
char cu_inbuf[1];
};
/*
* Connection less client creation returns with client handle parameters.
* Default options are set, which the user can change using clnt_control().
* fd should be open and bound.
* NB: The rpch->cl_auth is initialized to null authentication.
* Caller may wish to set this something more useful.
*
* sendsz and recvsz are the maximum allowable packet sizes that can be
* sent and received. Normally they are the same, but they can be
* changed to improve the program efficiency and buffer allocation.
* If they are 0, use the transport default.
*
* If svcaddr is NULL, returns NULL.
*/
CLIENT *
clnt_dg_create(fd, svcaddr, program, version, sendsz, recvsz)
int fd; /* open file descriptor */
const struct netbuf *svcaddr; /* servers address */
rpcprog_t program; /* program number */
rpcvers_t version; /* version number */
u_int sendsz; /* buffer recv size */
u_int recvsz; /* buffer send size */
{
CLIENT *cl = NULL; /* client handle */
struct cu_data *cu = NULL; /* private data */
struct timeval now;
struct rpc_msg call_msg;
sigset_t mask;
sigset_t newmask;
struct __rpc_sockinfo si;
int one = 1;
sigfillset(&newmask);
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
mutex_lock(&clnt_fd_lock);
if (dg_fd_locks == (int *) NULL) {
int cv_allocsz;
size_t fd_allocsz;
int dtbsize = __rpc_dtbsize();
fd_allocsz = dtbsize * sizeof (int);
dg_fd_locks = (int *) mem_alloc(fd_allocsz);
if (dg_fd_locks == (int *) NULL) {
mutex_unlock(&clnt_fd_lock);
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
goto err1;
} else
memset(dg_fd_locks, '\0', fd_allocsz);
cv_allocsz = dtbsize * sizeof (cond_t);
dg_cv = (cond_t *) mem_alloc(cv_allocsz);
if (dg_cv == (cond_t *) NULL) {
mem_free(dg_fd_locks, fd_allocsz);
dg_fd_locks = (int *) NULL;
mutex_unlock(&clnt_fd_lock);
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
goto err1;
} else {
int i;
for (i = 0; i < dtbsize; i++)
cond_init(&dg_cv[i], 0, (void *) 0);
}
}
mutex_unlock(&clnt_fd_lock);
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
if (svcaddr == NULL) {
rpc_createerr.cf_stat = RPC_UNKNOWNADDR;
return (NULL);
}
if (!__rpc_fd2sockinfo(fd, &si)) {
rpc_createerr.cf_stat = RPC_TLIERROR;
rpc_createerr.cf_error.re_errno = 0;
return (NULL);
}
/*
* Find the receive and the send size
*/
sendsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsz);
recvsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsz);
if ((sendsz == 0) || (recvsz == 0)) {
rpc_createerr.cf_stat = RPC_TLIERROR; /* XXX */
rpc_createerr.cf_error.re_errno = 0;
return (NULL);
}
if ((cl = mem_alloc(sizeof (CLIENT))) == NULL)
goto err1;
/*
* Should be multiple of 4 for XDR.
*/
sendsz = ((sendsz + 3) / 4) * 4;
recvsz = ((recvsz + 3) / 4) * 4;
cu = mem_alloc(sizeof (*cu) + sendsz + recvsz);
if (cu == NULL)
goto err1;
(void) memcpy(&cu->cu_raddr, svcaddr->buf, (size_t)svcaddr->len);
cu->cu_rlen = svcaddr->len;
cu->cu_outbuf = &cu->cu_inbuf[recvsz];
/* Other values can also be set through clnt_control() */
cu->cu_wait.tv_sec = 15; /* heuristically chosen */
cu->cu_wait.tv_usec = 0;
cu->cu_total.tv_sec = -1;
cu->cu_total.tv_usec = -1;
cu->cu_sendsz = sendsz;
cu->cu_recvsz = recvsz;
(void) gettimeofday(&now, NULL);
call_msg.rm_xid = __RPC_GETXID(&now);
call_msg.rm_call.cb_prog = program;
call_msg.rm_call.cb_vers = version;
xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf, sendsz, XDR_ENCODE);
if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) {
rpc_createerr.cf_stat = RPC_CANTENCODEARGS; /* XXX */
rpc_createerr.cf_error.re_errno = 0;
goto err2;
}
cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));
/* XXX fvdl - do we still want this? */
#if 0
(void)bindresvport_sa(fd, (struct sockaddr *)svcaddr->buf);
#endif
_ioctl(fd, FIONBIO, (char *)(void *)&one);
/*
* By default, closeit is always FALSE. It is users responsibility
* to do a close on it, else the user may use clnt_control
* to let clnt_destroy do it for him/her.
*/
cu->cu_closeit = FALSE;
cu->cu_fd = fd;
cl->cl_ops = clnt_dg_ops();
cl->cl_private = (caddr_t)(void *)cu;
cl->cl_auth = authnone_create();
cl->cl_tp = NULL;
cl->cl_netid = NULL;
cu->pfdp.fd = cu->cu_fd;
cu->pfdp.events = POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND;
return (cl);
err1:
warnx(mem_err_clnt_dg);
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
err2:
if (cl) {
mem_free(cl, sizeof (CLIENT));
if (cu)
mem_free(cu, sizeof (*cu) + sendsz + recvsz);
}
return (NULL);
}
static enum clnt_stat
clnt_dg_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
CLIENT *cl; /* client handle */
rpcproc_t proc; /* procedure number */
xdrproc_t xargs; /* xdr routine for args */
caddr_t argsp; /* pointer to args */
xdrproc_t xresults; /* xdr routine for results */
caddr_t resultsp; /* pointer to results */
struct timeval utimeout; /* seconds to wait before giving up */
{
struct cu_data *cu = (struct cu_data *)cl->cl_private;
XDR *xdrs;
size_t outlen;
struct rpc_msg reply_msg;
XDR reply_xdrs;
struct timeval time_waited;
bool_t ok;
int nrefreshes = 2; /* number of times to refresh cred */
struct timeval timeout;
struct timeval retransmit_time;
struct timeval startime, curtime;
int firsttimeout = 1;
int dtbsize = __rpc_dtbsize();
sigset_t mask;
sigset_t newmask;
socklen_t fromlen, inlen;
ssize_t recvlen = 0;
int rpc_lock_value;
sigfillset(&newmask);
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
mutex_lock(&clnt_fd_lock);
while (dg_fd_locks[cu->cu_fd])
cond_wait(&dg_cv[cu->cu_fd], &clnt_fd_lock);
if (__isthreaded)
rpc_lock_value = 1;
else
rpc_lock_value = 0;
dg_fd_locks[cu->cu_fd] = rpc_lock_value;
mutex_unlock(&clnt_fd_lock);
if (cu->cu_total.tv_usec == -1) {
timeout = utimeout; /* use supplied timeout */
} else {
timeout = cu->cu_total; /* use default timeout */
}
time_waited.tv_sec = 0;
time_waited.tv_usec = 0;
retransmit_time = cu->cu_wait;
call_again:
xdrs = &(cu->cu_outxdrs);
xdrs->x_op = XDR_ENCODE;
XDR_SETPOS(xdrs, cu->cu_xdrpos);
/*
* the transaction is the first thing in the out buffer
*/
(*(u_int32_t *)(void *)(cu->cu_outbuf))++;
if ((! XDR_PUTINT32(xdrs, &proc)) ||
(! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
(! (*xargs)(xdrs, argsp))) {
release_fd_lock(cu->cu_fd, mask);
return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
}
outlen = (size_t)XDR_GETPOS(xdrs);
send_again:
if (_sendto(cu->cu_fd, cu->cu_outbuf, outlen, 0,
(struct sockaddr *)(void *)&cu->cu_raddr, (socklen_t)cu->cu_rlen)
!= outlen) {
cu->cu_error.re_errno = errno;
release_fd_lock(cu->cu_fd, mask);
return (cu->cu_error.re_status = RPC_CANTSEND);
}
/*
* Hack to provide rpc-based message passing
*/
if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
release_fd_lock(cu->cu_fd, mask);
return (cu->cu_error.re_status = RPC_TIMEDOUT);
}
/*
* sub-optimal code appears here because we have
* some clock time to spare while the packets are in flight.
* (We assume that this is actually only executed once.)
*/
reply_msg.acpted_rply.ar_verf = _null_auth;
reply_msg.acpted_rply.ar_results.where = resultsp;
reply_msg.acpted_rply.ar_results.proc = xresults;
for (;;) {
switch (_poll(&cu->pfdp, 1,
__rpc_timeval_to_msec(&retransmit_time))) {
case 0:
time_waited.tv_sec += retransmit_time.tv_sec;
time_waited.tv_usec += retransmit_time.tv_usec;
while (time_waited.tv_usec >= 1000000) {
time_waited.tv_sec++;
time_waited.tv_usec -= 1000000;
}
/* update retransmit_time */
if (retransmit_time.tv_sec < RPC_MAX_BACKOFF) {
retransmit_time.tv_usec *= 2;
retransmit_time.tv_sec *= 2;
while (retransmit_time.tv_usec >= 1000000) {
retransmit_time.tv_sec++;
retransmit_time.tv_usec -= 1000000;
}
}
if ((time_waited.tv_sec < timeout.tv_sec) ||
((time_waited.tv_sec == timeout.tv_sec) &&
(time_waited.tv_usec < timeout.tv_usec)))
goto send_again;
release_fd_lock(cu->cu_fd, mask);
return (cu->cu_error.re_status = RPC_TIMEDOUT);
case -1:
if (errno == EBADF) {
cu->cu_error.re_errno = errno;
release_fd_lock(cu->cu_fd, mask);
return (cu->cu_error.re_status = RPC_CANTRECV);
}
if (errno != EINTR) {
errno = 0; /* reset it */
continue;
}
/* interrupted by another signal, update time_waited */
if (firsttimeout) {
/*
* Could have done gettimeofday before clnt_call
* but that means 1 more system call per each
* clnt_call, so do it after first time out
*/
if (gettimeofday(&startime,
(struct timezone *) NULL) == -1) {
errno = 0;
continue;
}
firsttimeout = 0;
errno = 0;
continue;
};
if (gettimeofday(&curtime,
(struct timezone *) NULL) == -1) {
errno = 0;
continue;
};
time_waited.tv_sec += curtime.tv_sec - startime.tv_sec;
time_waited.tv_usec += curtime.tv_usec -
startime.tv_usec;
while (time_waited.tv_usec < 0) {
time_waited.tv_sec--;
time_waited.tv_usec += 1000000;
};
while (time_waited.tv_usec >= 1000000) {
time_waited.tv_sec++;
time_waited.tv_usec -= 1000000;
}
startime.tv_sec = curtime.tv_sec;
startime.tv_usec = curtime.tv_usec;
if ((time_waited.tv_sec > timeout.tv_sec) ||
((time_waited.tv_sec == timeout.tv_sec) &&
(time_waited.tv_usec > timeout.tv_usec))) {
release_fd_lock(cu->cu_fd, mask);
return (cu->cu_error.re_status = RPC_TIMEDOUT);
}
errno = 0; /* reset it */
continue;
};
if (cu->pfdp.revents & POLLNVAL || (cu->pfdp.revents == 0)) {
cu->cu_error.re_status = RPC_CANTRECV;
/*
* Note: we're faking errno here because we
* previously would have expected _poll() to
* return -1 with errno EBADF. Poll(BA_OS)
* returns 0 and sets the POLLNVAL revents flag
* instead.
*/
cu->cu_error.re_errno = errno = EBADF;
release_fd_lock(cu->cu_fd, mask);
return (-1);
}
/* We have some data now */
do {
if (errno == EINTR) {
/*
* Must make sure errno was not already
* EINTR in case _recvfrom() returns -1.
*/
errno = 0;
}
fromlen = sizeof (struct sockaddr_storage);
recvlen = _recvfrom(cu->cu_fd, cu->cu_inbuf,
cu->cu_recvsz, 0, (struct sockaddr *)(void *)&cu->cu_raddr,
&fromlen);
} while (recvlen < 0 && errno == EINTR);
if (recvlen < 0) {
if (errno == EWOULDBLOCK)
continue;
cu->cu_error.re_errno = errno;
release_fd_lock(cu->cu_fd, mask);
return (cu->cu_error.re_status = RPC_CANTRECV);
}
if (recvlen < sizeof (u_int32_t))
continue;
/* see if reply transaction id matches sent id */
if (*((u_int32_t *)(void *)(cu->cu_inbuf)) !=
*((u_int32_t *)(void *)(cu->cu_outbuf)))
continue;
/* we now assume we have the proper reply */
break;
}
inlen = (socklen_t)recvlen;
/*
* now decode and validate the response
*/
xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int)inlen, XDR_DECODE);
ok = xdr_replymsg(&reply_xdrs, &reply_msg);
/* XDR_DESTROY(&reply_xdrs); save a few cycles on noop destroy */
if (ok) {
if ((reply_msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
(reply_msg.acpted_rply.ar_stat == SUCCESS))
cu->cu_error.re_status = RPC_SUCCESS;
else
_seterr_reply(&reply_msg, &(cu->cu_error));
if (cu->cu_error.re_status == RPC_SUCCESS) {
if (! AUTH_VALIDATE(cl->cl_auth,
&reply_msg.acpted_rply.ar_verf)) {
cu->cu_error.re_status = RPC_AUTHERROR;
cu->cu_error.re_why = AUTH_INVALIDRESP;
}
if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
xdrs->x_op = XDR_FREE;
(void) xdr_opaque_auth(xdrs,
&(reply_msg.acpted_rply.ar_verf));
}
} /* end successful completion */
/*
* If unsuccesful AND error is an authentication error
* then refresh credentials and try again, else break
*/
else if (cu->cu_error.re_status == RPC_AUTHERROR)
/* maybe our credentials need to be refreshed ... */
if (nrefreshes > 0 &&
AUTH_REFRESH(cl->cl_auth, &reply_msg)) {
nrefreshes--;
goto call_again;
}
/* end of unsuccessful completion */
} /* end of valid reply message */
else {
cu->cu_error.re_status = RPC_CANTDECODERES;
}
release_fd_lock(cu->cu_fd, mask);
return (cu->cu_error.re_status);
}
static void
clnt_dg_geterr(cl, errp)
CLIENT *cl;
struct rpc_err *errp;
{
struct cu_data *cu = (struct cu_data *)cl->cl_private;
*errp = cu->cu_error;
}
static bool_t
clnt_dg_freeres(cl, xdr_res, res_ptr)
CLIENT *cl;
xdrproc_t xdr_res;
caddr_t res_ptr;
{
struct cu_data *cu = (struct cu_data *)cl->cl_private;
XDR *xdrs = &(cu->cu_outxdrs);
bool_t dummy;
sigset_t mask;
sigset_t newmask;
sigfillset(&newmask);
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
mutex_lock(&clnt_fd_lock);
while (dg_fd_locks[cu->cu_fd])
cond_wait(&dg_cv[cu->cu_fd], &clnt_fd_lock);
xdrs->x_op = XDR_FREE;
dummy = (*xdr_res)(xdrs, res_ptr);
mutex_unlock(&clnt_fd_lock);
thr_sigsetmask(SIG_SETMASK, &mask, NULL);
cond_signal(&dg_cv[cu->cu_fd]);
return (dummy);
}
/*ARGSUSED*/
static void
clnt_dg_abort(h)
CLIENT *h;
{
}
static bool_t
clnt_dg_control(cl, request, info)
CLIENT *cl;
u_int request;
char *info;
{
struct cu_data *cu = (struct cu_data *)cl->cl_private;
struct netbuf *addr;
sigset_t mask;
sigset_t newmask;
int rpc_lock_value;
sigfillset(&newmask);
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
mutex_lock(&clnt_fd_lock);
while (dg_fd_locks[cu->cu_fd])
cond_wait(&dg_cv[cu->cu_fd], &clnt_fd_lock);
if (__isthreaded)
rpc_lock_value = 1;
else
rpc_lock_value = 0;
dg_fd_locks[cu->cu_fd] = rpc_lock_value;
mutex_unlock(&clnt_fd_lock);
switch (request) {
case CLSET_FD_CLOSE:
cu->cu_closeit = TRUE;
release_fd_lock(cu->cu_fd, mask);
return (TRUE);
case CLSET_FD_NCLOSE:
cu->cu_closeit = FALSE;
release_fd_lock(cu->cu_fd, mask);
return (TRUE);
}
/* for other requests which use info */
if (info == NULL) {
release_fd_lock(cu->cu_fd, mask);
return (FALSE);
}
switch (request) {
case CLSET_TIMEOUT:
if (time_not_ok((struct timeval *)(void *)info)) {
release_fd_lock(cu->cu_fd, mask);
return (FALSE);
}
cu->cu_total = *(struct timeval *)(void *)info;
break;
case CLGET_TIMEOUT:
*(struct timeval *)(void *)info = cu->cu_total;
break;
case CLGET_SERVER_ADDR: /* Give him the fd address */
/* Now obsolete. Only for backward compatibility */
(void) memcpy(info, &cu->cu_raddr, (size_t)cu->cu_rlen);
break;
case CLSET_RETRY_TIMEOUT:
if (time_not_ok((struct timeval *)(void *)info)) {
release_fd_lock(cu->cu_fd, mask);
return (FALSE);
}
cu->cu_wait = *(struct timeval *)(void *)info;
break;
case CLGET_RETRY_TIMEOUT:
*(struct timeval *)(void *)info = cu->cu_wait;
break;
case CLGET_FD:
*(int *)(void *)info = cu->cu_fd;
break;
case CLGET_SVC_ADDR:
addr = (struct netbuf *)(void *)info;
addr->buf = &cu->cu_raddr;
addr->len = cu->cu_rlen;
addr->maxlen = sizeof cu->cu_raddr;
break;
case CLSET_SVC_ADDR: /* set to new address */
addr = (struct netbuf *)(void *)info;
if (addr->len < sizeof cu->cu_raddr)
return (FALSE);
(void) memcpy(&cu->cu_raddr, addr->buf, addr->len);
cu->cu_rlen = addr->len;
break;
case CLGET_XID:
/*
* use the knowledge that xid is the
* first element in the call structure *.
* This will get the xid of the PREVIOUS call
*/
*(u_int32_t *)(void *)info =
ntohl(*(u_int32_t *)(void *)cu->cu_outbuf);
break;
case CLSET_XID:
/* This will set the xid of the NEXT call */
*(u_int32_t *)(void *)cu->cu_outbuf =
htonl(*(u_int32_t *)(void *)info - 1);
/* decrement by 1 as clnt_dg_call() increments once */
break;
case CLGET_VERS:
/*
* This RELIES on the information that, in the call body,
* the version number field is the fifth field from the
* begining of the RPC header. MUST be changed if the
* call_struct is changed
*/
*(u_int32_t *)(void *)info =
ntohl(*(u_int32_t *)(void *)(cu->cu_outbuf +
4 * BYTES_PER_XDR_UNIT));
break;
case CLSET_VERS:
*(u_int32_t *)(void *)(cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT)
= htonl(*(u_int32_t *)(void *)info);
break;
case CLGET_PROG:
/*
* This RELIES on the information that, in the call body,
* the program number field is the fourth field from the
* begining of the RPC header. MUST be changed if the
* call_struct is changed
*/
*(u_int32_t *)(void *)info =
ntohl(*(u_int32_t *)(void *)(cu->cu_outbuf +
3 * BYTES_PER_XDR_UNIT));
break;
case CLSET_PROG:
*(u_int32_t *)(void *)(cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT)
= htonl(*(u_int32_t *)(void *)info);
break;
default:
release_fd_lock(cu->cu_fd, mask);
return (FALSE);
}
release_fd_lock(cu->cu_fd, mask);
return (TRUE);
}
static void
clnt_dg_destroy(cl)
CLIENT *cl;
{
struct cu_data *cu = (struct cu_data *)cl->cl_private;
int cu_fd = cu->cu_fd;
sigset_t mask;
sigset_t newmask;
sigfillset(&newmask);
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
mutex_lock(&clnt_fd_lock);
while (dg_fd_locks[cu_fd])
cond_wait(&dg_cv[cu_fd], &clnt_fd_lock);
if (cu->cu_closeit)
(void)_close(cu_fd);
XDR_DESTROY(&(cu->cu_outxdrs));
mem_free(cu, (sizeof (*cu) + cu->cu_sendsz + cu->cu_recvsz));
if (cl->cl_netid && cl->cl_netid[0])
mem_free(cl->cl_netid, strlen(cl->cl_netid) +1);
if (cl->cl_tp && cl->cl_tp[0])
mem_free(cl->cl_tp, strlen(cl->cl_tp) +1);
mem_free(cl, sizeof (CLIENT));
mutex_unlock(&clnt_fd_lock);
thr_sigsetmask(SIG_SETMASK, &mask, NULL);
cond_signal(&dg_cv[cu_fd]);
}
static struct clnt_ops *
clnt_dg_ops()
{
static struct clnt_ops ops;
extern mutex_t ops_lock;
sigset_t mask;
sigset_t newmask;
/* VARIABLES PROTECTED BY ops_lock: ops */
sigfillset(&newmask);
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
mutex_lock(&ops_lock);
if (ops.cl_call == NULL) {
ops.cl_call = clnt_dg_call;
ops.cl_abort = clnt_dg_abort;
ops.cl_geterr = clnt_dg_geterr;
ops.cl_freeres = clnt_dg_freeres;
ops.cl_destroy = clnt_dg_destroy;
ops.cl_control = clnt_dg_control;
}
mutex_unlock(&ops_lock);
thr_sigsetmask(SIG_SETMASK, &mask, NULL);
return (&ops);
}
/*
* Make sure that the time is not garbage. -1 value is allowed.
*/
static bool_t
time_not_ok(t)
struct timeval *t;
{
return (t->tv_sec < -1 || t->tv_sec > 100000000 ||
t->tv_usec < -1 || t->tv_usec > 1000000);
}
/*
* Convert from timevals (used by select) to milliseconds (used by poll).
*/
static int
__rpc_timeval_to_msec(t)
struct timeval *t;
{
int t1, tmp;
/*
* We're really returning t->tv_sec * 1000 + (t->tv_usec / 1000)
* but try to do so efficiently. Note: 1000 = 1024 - 16 - 8.
*/
tmp = (int)t->tv_sec << 3;
t1 = -tmp;
t1 += t1 << 1;
t1 += tmp << 7;
if (t->tv_usec)
t1 += (int)(t->tv_usec / 1000);
return (t1);
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: clnt_generic.c,v 1.18 2000/07/06 03:10:34 christos Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -27,6 +29,8 @@
* Mountain View, California 94043
*/
/* #ident "@(#)clnt_generic.c 1.20 94/05/03 SMI" */
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI";*/
/*static char *sccsid = "from: @(#)clnt_generic.c 2.2 88/08/01 4.0 RPCSRC";*/
@ -34,104 +38,312 @@ static char *rcsid = "$FreeBSD$";
#endif
/*
* Copyright (C) 1987, Sun Microsystems, Inc.
* Copyright (c) 1986-1991 by Sun Microsystems Inc.
*/
#include <rpc/rpc.h>
#include "reentrant.h"
#include "namespace.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <stdio.h>
#include <errno.h>
#include <netdb.h>
#include <rpc/rpc.h>
#include <rpc/nettype.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "un-namespace.h"
#include "rpc_com.h"
/*
* Generic client creation: takes (hostname, program-number, protocol) and
* returns client handle. Default options are set, which the user can
* change using the rpc equivalent of _ioctl()'s.
* Generic client creation with version checking the value of
* vers_out is set to the highest server supported value
* vers_low <= vers_out <= vers_high AND an error results
* if this can not be done.
*/
CLIENT *
clnt_create(hostname, prog, vers, proto)
char *hostname;
u_long prog;
u_long vers;
char *proto;
clnt_create_vers(hostname, prog, vers_out, vers_low, vers_high, nettype)
const char *hostname;
rpcprog_t prog;
rpcvers_t *vers_out;
rpcvers_t vers_low;
rpcvers_t vers_high;
const char *nettype;
{
struct hostent *h;
struct protoent *p;
struct sockaddr_in sin;
struct sockaddr_un sun;
int sock;
static struct timeval tv;
CLIENT *client;
CLIENT *clnt;
struct timeval to;
enum clnt_stat rpc_stat;
struct rpc_err rpcerr;
if (!strcmp(proto, "unix")) {
bzero((char *)&sun, sizeof(sun));
sun.sun_family = AF_UNIX;
strcpy(sun.sun_path, hostname);
sun.sun_len = sizeof(sun.sun_len) + sizeof(sun.sun_family) +
strlen(sun.sun_path) + 1;
sock = RPC_ANYSOCK;
client = clntunix_create(&sun, prog, vers, &sock, 0, 0);
if (client == NULL)
return(NULL);
tv.tv_sec = 25;
tv.tv_usec = 0;
clnt_control(client, CLSET_TIMEOUT, &tv);
return(client);
}
h = gethostbyname(hostname);
if (h == NULL) {
rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
clnt = clnt_create(hostname, prog, vers_high, nettype);
if (clnt == NULL) {
return (NULL);
}
if (h->h_addrtype != AF_INET) {
/*
* Only support INET for now
*/
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = EAFNOSUPPORT;
return (NULL);
to.tv_sec = 10;
to.tv_usec = 0;
rpc_stat = clnt_call(clnt, NULLPROC, (xdrproc_t) xdr_void,
(char *) NULL, (xdrproc_t) xdr_void, (char *) NULL, to);
if (rpc_stat == RPC_SUCCESS) {
*vers_out = vers_high;
return (clnt);
}
memset(&sin, 0, sizeof(sin));
sin.sin_len = sizeof(struct sockaddr_in);
sin.sin_family = h->h_addrtype;
sin.sin_port = 0;
memcpy((char*)&sin.sin_addr, h->h_addr, h->h_length);
p = getprotobyname(proto);
if (p == NULL) {
if (rpc_stat == RPC_PROGVERSMISMATCH) {
unsigned long minvers, maxvers;
clnt_geterr(clnt, &rpcerr);
minvers = rpcerr.re_vers.low;
maxvers = rpcerr.re_vers.high;
if (maxvers < vers_high)
vers_high = (rpcvers_t)maxvers;
if (minvers > vers_low)
vers_low = (rpcvers_t)minvers;
if (vers_low > vers_high) {
goto error;
}
CLNT_CONTROL(clnt, CLSET_VERS, (char *)(void *)&vers_high);
rpc_stat = clnt_call(clnt, NULLPROC, (xdrproc_t) xdr_void,
(char *) NULL, (xdrproc_t) xdr_void,
(char *) NULL, to);
if (rpc_stat == RPC_SUCCESS) {
*vers_out = vers_high;
return (clnt);
}
}
clnt_geterr(clnt, &rpcerr);
error:
rpc_createerr.cf_stat = rpc_stat;
rpc_createerr.cf_error = rpcerr;
clnt_destroy(clnt);
return (NULL);
}
/*
* Top level client creation routine.
* Generic client creation: takes (servers name, program-number, nettype) and
* returns client handle. Default options are set, which the user can
* change using the rpc equivalent of _ioctl()'s.
*
* It tries for all the netids in that particular class of netid until
* it succeeds.
* XXX The error message in the case of failure will be the one
* pertaining to the last create error.
*
* It calls clnt_tp_create();
*/
CLIENT *
clnt_create(hostname, prog, vers, nettype)
const char *hostname; /* server name */
rpcprog_t prog; /* program number */
rpcvers_t vers; /* version number */
const char *nettype; /* net type */
{
struct netconfig *nconf;
CLIENT *clnt = NULL;
void *handle;
enum clnt_stat save_cf_stat = RPC_SUCCESS;
struct rpc_err save_cf_error;
if ((handle = __rpc_setconf(nettype)) == NULL) {
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
rpc_createerr.cf_error.re_errno = EPFNOSUPPORT;
return (NULL);
}
sock = RPC_ANYSOCK;
switch (p->p_proto) {
case IPPROTO_UDP:
tv.tv_sec = 5;
tv.tv_usec = 0;
client = clntudp_create(&sin, prog, vers, tv, &sock);
if (client == NULL) {
rpc_createerr.cf_stat = RPC_SUCCESS;
while (clnt == NULL) {
if ((nconf = __rpc_getconf(handle)) == NULL) {
if (rpc_createerr.cf_stat == RPC_SUCCESS)
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
break;
}
#ifdef CLNT_DEBUG
printf("trying netid %s\n", nconf->nc_netid);
#endif
clnt = clnt_tp_create(hostname, prog, vers, nconf);
if (clnt)
break;
else
/*
* Since we didn't get a name-to-address
* translation failure here, we remember
* this particular error. The object of
* this is to enable us to return to the
* caller a more-specific error than the
* unhelpful ``Name to address translation
* failed'' which might well occur if we
* merely returned the last error (because
* the local loopbacks are typically the
* last ones in /etc/netconfig and the most
* likely to be unable to translate a host
* name).
*/
if (rpc_createerr.cf_stat != RPC_N2AXLATEFAILURE) {
save_cf_stat = rpc_createerr.cf_stat;
save_cf_error = rpc_createerr.cf_error;
}
}
/*
* Attempt to return an error more specific than ``Name to address
* translation failed''
*/
if ((rpc_createerr.cf_stat == RPC_N2AXLATEFAILURE) &&
(save_cf_stat != RPC_SUCCESS)) {
rpc_createerr.cf_stat = save_cf_stat;
rpc_createerr.cf_error = save_cf_error;
}
__rpc_endconf(handle);
return (clnt);
}
/*
* Generic client creation: takes (servers name, program-number, netconf) and
* returns client handle. Default options are set, which the user can
* change using the rpc equivalent of _ioctl()'s : clnt_control()
* It finds out the server address from rpcbind and calls clnt_tli_create()
*/
CLIENT *
clnt_tp_create(hostname, prog, vers, nconf)
const char *hostname; /* server name */
rpcprog_t prog; /* program number */
rpcvers_t vers; /* version number */
const struct netconfig *nconf; /* net config struct */
{
struct netbuf *svcaddr; /* servers address */
CLIENT *cl = NULL; /* client handle */
if (nconf == NULL) {
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
return (NULL);
}
/*
* Get the address of the server
*/
if ((svcaddr = __rpcb_findaddr(prog, vers, nconf, hostname,
&cl)) == NULL) {
/* appropriate error number is set by rpcbind libraries */
return (NULL);
}
if (cl == NULL) {
cl = clnt_tli_create(RPC_ANYFD, nconf, svcaddr,
prog, vers, 0, 0);
} else {
/* Reuse the CLIENT handle and change the appropriate fields */
if (CLNT_CONTROL(cl, CLSET_SVC_ADDR, (void *)svcaddr) == TRUE) {
if (cl->cl_netid == NULL)
cl->cl_netid = strdup(nconf->nc_netid);
if (cl->cl_tp == NULL)
cl->cl_tp = strdup(nconf->nc_device);
(void) CLNT_CONTROL(cl, CLSET_PROG, (void *)&prog);
(void) CLNT_CONTROL(cl, CLSET_VERS, (void *)&vers);
} else {
CLNT_DESTROY(cl);
cl = clnt_tli_create(RPC_ANYFD, nconf, svcaddr,
prog, vers, 0, 0);
}
}
free(svcaddr->buf);
free(svcaddr);
return (cl);
}
/*
* Generic client creation: returns client handle.
* Default options are set, which the user can
* change using the rpc equivalent of _ioctl()'s : clnt_control().
* If fd is RPC_ANYFD, it will be opened using nconf.
* It will be bound if not so.
* If sizes are 0; appropriate defaults will be chosen.
*/
CLIENT *
clnt_tli_create(fd, nconf, svcaddr, prog, vers, sendsz, recvsz)
int fd; /* fd */
const struct netconfig *nconf; /* netconfig structure */
const struct netbuf *svcaddr; /* servers address */
rpcprog_t prog; /* program number */
rpcvers_t vers; /* version number */
u_int sendsz; /* send size */
u_int recvsz; /* recv size */
{
CLIENT *cl; /* client handle */
bool_t madefd = FALSE; /* whether fd opened here */
long servtype;
int one = 1;
struct __rpc_sockinfo si;
if (fd == RPC_ANYFD) {
if (nconf == NULL) {
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
return (NULL);
}
#if 0 /* XXX do we need this? */
tv.tv_sec = 25;
tv.tv_usec = 0;
clnt_control(client, CLSET_TIMEOUT, &tv);
#endif
fd = __rpc_nconf2fd(nconf);
if (fd == -1)
goto err;
madefd = TRUE;
servtype = nconf->nc_semantics;
if (!__rpc_fd2sockinfo(fd, &si))
goto err;
bindresvport(fd, NULL);
} else {
if (!__rpc_fd2sockinfo(fd, &si))
goto err;
servtype = __rpc_socktype2seman(si.si_socktype);
if (servtype == -1) {
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
return NULL;
}
}
if (si.si_af != ((struct sockaddr *)svcaddr->buf)->sa_family) {
rpc_createerr.cf_stat = RPC_UNKNOWNHOST; /* XXX */
goto err1;
}
switch (servtype) {
case NC_TPI_COTS_ORD:
cl = clnt_vc_create(fd, svcaddr, prog, vers, sendsz, recvsz);
if (!nconf || !cl)
break;
/* XXX fvdl - is this useful? */
if (strncmp(nconf->nc_protofmly, "inet", 4) == 0)
_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one,
sizeof (one));
break;
case IPPROTO_TCP:
client = clnttcp_create(&sin, prog, vers, &sock, 0, 0);
if (client == NULL) {
return (NULL);
}
#if 0 /* XXX do we need this? */
tv.tv_sec = 25;
tv.tv_usec = 0;
clnt_control(client, CLSET_TIMEOUT, &tv);
#endif
case NC_TPI_CLTS:
cl = clnt_dg_create(fd, svcaddr, prog, vers, sendsz, recvsz);
break;
default:
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = EPFNOSUPPORT;
return (NULL);
goto err;
}
return (client);
if (cl == NULL)
goto err1; /* borrow errors from clnt_dg/vc creates */
if (nconf) {
cl->cl_netid = strdup(nconf->nc_netid);
cl->cl_tp = strdup(nconf->nc_device);
} else {
cl->cl_netid = "";
cl->cl_tp = "";
}
if (madefd) {
(void) CLNT_CONTROL(cl, CLSET_FD_CLOSE, NULL);
/* (void) CLNT_CONTROL(cl, CLSET_POP_TIMOD, (char *) NULL); */
};
return (cl);
err:
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
err1: if (madefd)
(void)_close(fd);
return (NULL);
}

View File

@ -1,3 +1,6 @@
/* $NetBSD: clnt_perror.c,v 1.24 2000/06/02 23:11:07 fvdl Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -27,9 +30,10 @@
* Mountain View, California 94043
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)clnt_perror.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *sccsid = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";
static char *sccsid = "@(#)clnt_perror.c 2.1 88/07/29 4.0 RPCSRC";
static char *rcsid = "$FreeBSD$";
#endif
@ -39,19 +43,24 @@ static char *rcsid = "$FreeBSD$";
* Copyright (C) 1984, Sun Microsystems, Inc.
*
*/
#include "namespace.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rpc/rpc.h>
#include <rpc/types.h>
#include <rpc/auth.h>
#include <rpc/clnt.h>
static char *auth_errmsg();
#define CLNT_PERROR_BUFLEN 256
#include "un-namespace.h"
static char *buf;
static char *_buf __P((void));
static char *auth_errmsg __P((enum auth_stat));
#define CLNT_PERROR_BUFLEN 256
static char *
_buf()
{
@ -67,19 +76,32 @@ _buf()
char *
clnt_sperror(rpch, s)
CLIENT *rpch;
char *s;
const char *s;
{
struct rpc_err e;
char *err;
char *str = _buf();
char *strstart = str;
char *str;
char *strstart;
size_t len, i;
assert(rpch != NULL);
assert(s != NULL);
str = _buf(); /* side effect: sets CLNT_PERROR_BUFLEN */
if (str == 0)
return (0);
len = CLNT_PERROR_BUFLEN;
strstart = str;
CLNT_GETERR(rpch, &e);
(void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s", s, clnt_sperrno(e.re_status));
str += strlen(str);
i = snprintf(str, len, "%s: ", s);
str += i;
len -= i;
(void)strncpy(str, clnt_sperrno(e.re_status), len - 1);
i = strlen(str);
str += i;
len -= i;
switch (e.re_status) {
case RPC_SUCCESS:
@ -99,42 +121,48 @@ clnt_sperror(rpch, s)
case RPC_CANTSEND:
case RPC_CANTRECV:
(void) snprintf(str, CLNT_PERROR_BUFLEN - (str - strstart),
"; errno = %s\n", strerror(e.re_errno));
i = snprintf(str, len, "; errno = %s", strerror(e.re_errno));
str += i;
len -= i;
break;
case RPC_VERSMISMATCH:
(void) sprintf(str,
"; low version = %lu, high version = %lu\n",
(u_long)e.re_vers.low, (u_long)e.re_vers.high);
i = snprintf(str, len, "; low version = %u, high version = %u",
e.re_vers.low, e.re_vers.high);
str += i;
len -= i;
break;
case RPC_AUTHERROR:
err = auth_errmsg(e.re_why);
(void) sprintf(str,"; why = ");
str += strlen(str);
i = snprintf(str, len, "; why = ");
str += i;
len -= i;
if (err != NULL) {
(void) sprintf(str, "%s\n",err);
i = snprintf(str, len, "%s",err);
} else {
(void) sprintf(str,
"(unknown authentication error - %d)\n",
i = snprintf(str, len,
"(unknown authentication error - %d)",
(int) e.re_why);
}
str += i;
len -= i;
break;
case RPC_PROGVERSMISMATCH:
(void) sprintf(str,
"; low version = %lu, high version = %lu\n",
(u_long)e.re_vers.low, (u_long)e.re_vers.high);
i = snprintf(str, len, "; low version = %u, high version = %u",
e.re_vers.low, e.re_vers.high);
str += i;
len -= i;
break;
default: /* unknown */
(void) sprintf(str,
"; s1 = %lu, s2 = %lu\n",
(long)e.re_lb.s1, (long)e.re_lb.s2);
i = snprintf(str, len, "; s1 = %u, s2 = %u",
e.re_lb.s1, e.re_lb.s2);
str += i;
len -= i;
break;
}
strstart[CLNT_PERROR_BUFLEN-2] = '\n';
strstart[CLNT_PERROR_BUFLEN-1] = '\0';
return(strstart) ;
}
@ -142,11 +170,14 @@ clnt_sperror(rpch, s)
void
clnt_perror(rpch, s)
CLIENT *rpch;
char *s;
const char *s;
{
(void) fprintf(stderr,"%s\n",clnt_sperror(rpch,s));
}
assert(rpch != NULL);
assert(s != NULL);
(void) fprintf(stderr, "%s\n", clnt_sperror(rpch,s));
}
static const char *const rpc_errlist[] = {
"RPC: Success", /* 0 - RPC_SUCCESS */
@ -180,6 +211,7 @@ clnt_sperrno(stat)
unsigned int errnum = stat;
if (errnum < (sizeof(rpc_errlist)/sizeof(rpc_errlist[0])))
/* LINTED interface problem */
return (char *)rpc_errlist[errnum];
return ("RPC: (unknown error code)");
@ -189,53 +221,78 @@ void
clnt_perrno(num)
enum clnt_stat num;
{
(void) fprintf(stderr,"%s\n",clnt_sperrno(num));
(void) fprintf(stderr, "%s\n", clnt_sperrno(num));
}
char *
clnt_spcreateerror(s)
char *s;
const char *s;
{
char *str = _buf();
char *str;
size_t len, i;
assert(s != NULL);
str = _buf(); /* side effect: sets CLNT_PERROR_BUFLEN */
if (str == 0)
return(0);
len = CLNT_PERROR_BUFLEN;
i = snprintf(str, len, "%s: ", s);
len -= i;
(void)strncat(str, clnt_sperrno(rpc_createerr.cf_stat), len - 1);
switch (rpc_createerr.cf_stat) {
case RPC_PMAPFAILURE:
(void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s,
clnt_sperrno(rpc_createerr.cf_stat),
clnt_sperrno(rpc_createerr.cf_error.re_status));
(void) strncat(str, " - ", len - 1);
(void) strncat(str,
clnt_sperrno(rpc_createerr.cf_error.re_status), len - 4);
break;
case RPC_SYSTEMERROR:
(void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s,
clnt_sperrno(rpc_createerr.cf_stat),
strerror(rpc_createerr.cf_error.re_errno));
(void)strncat(str, " - ", len - 1);
(void)strncat(str, strerror(rpc_createerr.cf_error.re_errno),
len - 4);
break;
case RPC_CANTSEND:
case RPC_CANTDECODERES:
case RPC_CANTENCODEARGS:
case RPC_SUCCESS:
case RPC_UNKNOWNPROTO:
case RPC_PROGNOTREGISTERED:
case RPC_FAILED:
case RPC_UNKNOWNHOST:
case RPC_CANTDECODEARGS:
case RPC_PROCUNAVAIL:
case RPC_PROGVERSMISMATCH:
case RPC_PROGUNAVAIL:
case RPC_AUTHERROR:
case RPC_VERSMISMATCH:
case RPC_TIMEDOUT:
case RPC_CANTRECV:
default:
(void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s\n", s,
clnt_sperrno(rpc_createerr.cf_stat));
break;
}
str[CLNT_PERROR_BUFLEN-2] = '\n';
str[CLNT_PERROR_BUFLEN-1] = '\0';
return (str);
}
void
clnt_pcreateerror(s)
char *s;
const char *s;
{
(void) fprintf(stderr,"%s\n",clnt_spcreateerror(s));
assert(s != NULL);
(void) fprintf(stderr, "%s\n", clnt_spcreateerror(s));
}
static const char *const auth_errlist[] = {
"Authentication OK", /* 0 - AUTH_OK */
"Invalid client credential", /* 1 - AUTH_BADCRED */
"Server rejected credential", /* 2 - AUTH_REJECTEDCRED */
"Invalid client verifier", /* 3 - AUTH_BADVERF */
"Server rejected verifier", /* 4 - AUTH_REJECTEDVERF */
"Invalid client verifier", /* 3 - AUTH_BADVERF */
"Server rejected verifier", /* 4 - AUTH_REJECTEDVERF */
"Client credential too weak", /* 5 - AUTH_TOOWEAK */
"Invalid server verifier", /* 6 - AUTH_INVALIDRESP */
"Failed (unspecified error)" /* 7 - AUTH_FAILED */
@ -248,6 +305,7 @@ auth_errmsg(stat)
unsigned int errnum = stat;
if (errnum < (sizeof(auth_errlist)/sizeof(auth_errlist[0])))
/* LINTED interface problem */
return (char *)auth_errlist[errnum];
return(NULL);

View File

@ -1,3 +1,5 @@
/* $NetBSD: clnt_raw.c,v 1.20 2000/12/10 04:12:03 christos Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -27,9 +29,10 @@
* Mountain View, California 94043
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC";*/
static char *sccsid = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";
static char *sccsid = "@(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC";
static char *rcsid = "$FreeBSD$";
#endif
@ -44,9 +47,18 @@ static char *rcsid = "$FreeBSD$";
* any interference from the kernal.
*/
#include <rpc/rpc.h>
#include <stdlib.h>
#include "reentrant.h"
#include "namespace.h"
#include <assert.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <rpc/rpc.h>
#include <rpc/raw.h>
#include "un-namespace.h"
extern mutex_t clntraw_lock;
#define MCALL_MSG_SIZE 24
@ -56,46 +68,47 @@ static char *rcsid = "$FreeBSD$";
static struct clntraw_private {
CLIENT client_object;
XDR xdr_stream;
char _raw_buf[UDPMSGSIZE];
char mashl_callmsg[MCALL_MSG_SIZE];
char *_raw_buf;
union {
struct rpc_msg mashl_rpcmsg;
char mashl_callmsg[MCALL_MSG_SIZE];
} u;
u_int mcnt;
} *clntraw_private;
static enum clnt_stat clntraw_call();
static void clntraw_abort();
static void clntraw_geterr();
static bool_t clntraw_freeres();
static bool_t clntraw_control();
static void clntraw_destroy();
static struct clnt_ops client_ops = {
clntraw_call,
clntraw_abort,
clntraw_geterr,
clntraw_freeres,
clntraw_destroy,
clntraw_control
};
void svc_getreq();
static enum clnt_stat clnt_raw_call __P((CLIENT *, rpcproc_t, xdrproc_t,
caddr_t, xdrproc_t, caddr_t, struct timeval));
static void clnt_raw_geterr __P((CLIENT *, struct rpc_err *));
static bool_t clnt_raw_freeres __P((CLIENT *, xdrproc_t, caddr_t));
static void clnt_raw_abort __P((CLIENT *));
static bool_t clnt_raw_control __P((CLIENT *, u_int, char *));
static void clnt_raw_destroy __P((CLIENT *));
static struct clnt_ops *clnt_raw_ops __P((void));
/*
* Create a client handle for memory based rpc.
*/
CLIENT *
clntraw_create(prog, vers)
u_long prog;
u_long vers;
clnt_raw_create(prog, vers)
rpcprog_t prog;
rpcvers_t vers;
{
register struct clntraw_private *clp = clntraw_private;
struct clntraw_private *clp = clntraw_private;
struct rpc_msg call_msg;
XDR *xdrs = &clp->xdr_stream;
CLIENT *client = &clp->client_object;
if (clp == 0) {
mutex_lock(&clntraw_lock);
if (clp == NULL) {
clp = (struct clntraw_private *)calloc(1, sizeof (*clp));
if (clp == 0)
return (0);
if (clp == NULL) {
mutex_unlock(&clntraw_lock);
return NULL;
}
if (__rpc_rawcombuf == NULL)
__rpc_rawcombuf =
(char *)calloc(UDPMSGSIZE, sizeof (char));
clp->_raw_buf = __rpc_rawcombuf;
clntraw_private = clp;
}
/*
@ -103,12 +116,12 @@ clntraw_create(prog, vers)
*/
call_msg.rm_direction = CALL;
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
call_msg.rm_call.cb_prog = prog;
call_msg.rm_call.cb_vers = vers;
xdrmem_create(xdrs, clp->mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE);
if (! xdr_callhdr(xdrs, &call_msg)) {
perror("clnt_raw.c - Fatal header serialization error.");
}
/* XXX: prog and vers have been long historically :-( */
call_msg.rm_call.cb_prog = (u_int32_t)prog;
call_msg.rm_call.cb_vers = (u_int32_t)vers;
xdrmem_create(xdrs, clp->u.mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE);
if (! xdr_callhdr(xdrs, &call_msg))
warnx("clntraw_create - Fatal header serialization error.");
clp->mcnt = XDR_GETPOS(xdrs);
XDR_DESTROY(xdrs);
@ -120,38 +133,47 @@ clntraw_create(prog, vers)
/*
* create client handle
*/
client->cl_ops = &client_ops;
client->cl_ops = clnt_raw_ops();
client->cl_auth = authnone_create();
mutex_unlock(&clntraw_lock);
return (client);
}
static enum clnt_stat
clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
/* ARGSUSED */
static enum clnt_stat
clnt_raw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
CLIENT *h;
u_long proc;
rpcproc_t proc;
xdrproc_t xargs;
caddr_t argsp;
xdrproc_t xresults;
caddr_t resultsp;
struct timeval timeout;
{
register struct clntraw_private *clp = clntraw_private;
register XDR *xdrs = &clp->xdr_stream;
struct clntraw_private *clp = clntraw_private;
XDR *xdrs = &clp->xdr_stream;
struct rpc_msg msg;
enum clnt_stat status;
struct rpc_err error;
if (clp == 0)
assert(h != NULL);
mutex_lock(&clntraw_lock);
if (clp == NULL) {
mutex_unlock(&clntraw_lock);
return (RPC_FAILED);
}
mutex_unlock(&clntraw_lock);
call_again:
/*
* send request
*/
xdrs->x_op = XDR_ENCODE;
XDR_SETPOS(xdrs, 0);
((struct rpc_msg *)clp->mashl_callmsg)->rm_xid ++ ;
if ((! XDR_PUTBYTES(xdrs, clp->mashl_callmsg, clp->mcnt)) ||
(! XDR_PUTLONG(xdrs, (long *)&proc)) ||
clp->u.mashl_rpcmsg.rm_xid ++ ;
if ((! XDR_PUTBYTES(xdrs, clp->u.mashl_callmsg, clp->mcnt)) ||
(! XDR_PUTINT32(xdrs, &proc)) ||
(! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
(! (*xargs)(xdrs, argsp))) {
return (RPC_CANTENCODEARGS);
@ -162,7 +184,7 @@ clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
* We have to call server input routine here because this is
* all going on in one process. Yuk.
*/
svc_getreq(1);
svc_getreq_common(FD_SETSIZE);
/*
* get results
@ -172,8 +194,23 @@ clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
msg.acpted_rply.ar_verf = _null_auth;
msg.acpted_rply.ar_results.where = resultsp;
msg.acpted_rply.ar_results.proc = xresults;
if (! xdr_replymsg(xdrs, &msg))
if (! xdr_replymsg(xdrs, &msg)) {
/*
* It's possible for xdr_replymsg() to fail partway
* through its attempt to decode the result from the
* server. If this happens, it will leave the reply
* structure partially populated with dynamically
* allocated memory. (This can happen if someone uses
* clntudp_bufcreate() to create a CLIENT handle and
* specifies a receive buffer size that is too small.)
* This memory must be free()ed to avoid a leak.
*/
int op = xdrs->x_op;
xdrs->x_op = XDR_FREE;
xdr_replymsg(xdrs, &msg);
xdrs->x_op = op;
return (RPC_CANTDECODERES);
}
_seterr_reply(&msg, &error);
status = error.re_status;
@ -183,7 +220,7 @@ clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
}
} /* end successful completion */
else {
if (AUTH_REFRESH(h->cl_auth))
if (AUTH_REFRESH(h->cl_auth, &msg))
goto call_again;
} /* end of unsuccessful completion */
@ -200,43 +237,78 @@ clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
return (status);
}
/*ARGSUSED*/
static void
clntraw_geterr()
clnt_raw_geterr(cl, err)
CLIENT *cl;
struct rpc_err *err;
{
}
/* ARGSUSED */
static bool_t
clntraw_freeres(cl, xdr_res, res_ptr)
clnt_raw_freeres(cl, xdr_res, res_ptr)
CLIENT *cl;
xdrproc_t xdr_res;
caddr_t res_ptr;
{
register struct clntraw_private *clp = clntraw_private;
register XDR *xdrs = &clp->xdr_stream;
struct clntraw_private *clp = clntraw_private;
XDR *xdrs = &clp->xdr_stream;
bool_t rval;
if (clp == 0)
{
mutex_lock(&clntraw_lock);
if (clp == NULL) {
rval = (bool_t) RPC_FAILED;
mutex_unlock(&clntraw_lock);
return (rval);
}
mutex_unlock(&clntraw_lock);
xdrs->x_op = XDR_FREE;
return ((*xdr_res)(xdrs, res_ptr));
}
/*ARGSUSED*/
static void
clntraw_abort()
clnt_raw_abort(cl)
CLIENT *cl;
{
}
/*ARGSUSED*/
static bool_t
clntraw_control()
clnt_raw_control(cl, ui, str)
CLIENT *cl;
u_int ui;
char *str;
{
return (FALSE);
}
/*ARGSUSED*/
static void
clntraw_destroy()
clnt_raw_destroy(cl)
CLIENT *cl;
{
}
static struct clnt_ops *
clnt_raw_ops()
{
static struct clnt_ops ops;
extern mutex_t ops_lock;
/* VARIABLES PROTECTED BY ops_lock: ops */
mutex_lock(&ops_lock);
if (ops.cl_call == NULL) {
ops.cl_call = clnt_raw_call;
ops.cl_abort = clnt_raw_abort;
ops.cl_geterr = clnt_raw_geterr;
ops.cl_freeres = clnt_raw_freeres;
ops.cl_destroy = clnt_raw_destroy;
ops.cl_control = clnt_raw_control;
}
mutex_unlock(&ops_lock);
return (&ops);
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: clnt_simple.c,v 1.21 2000/07/06 03:10:34 christos Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -26,6 +28,9 @@
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1986-1991 by Sun Microsystems Inc.
*/
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";*/
@ -35,90 +40,156 @@ static char *rcsid = "$FreeBSD$";
/*
* clnt_simple.c
* Simplified front end to rpc.
* Simplified front end to client rpc.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*/
#include "reentrant.h"
#include "namespace.h"
#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include "un-namespace.h"
static struct callrpc_private {
CLIENT *client;
int socket;
int oldprognum, oldversnum, valid;
char *oldhost;
} *callrpc_private;
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 64
#endif
int
callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
char *host;
int prognum, versnum, procnum;
xdrproc_t inproc, outproc;
char *in, *out;
#ifndef NETIDLEN
#define NETIDLEN 32
#endif
struct rpc_call_private {
int valid; /* Is this entry valid ? */
CLIENT *client; /* Client handle */
pid_t pid; /* process-id at moment of creation */
rpcprog_t prognum; /* Program */
rpcvers_t versnum; /* Version */
char host[MAXHOSTNAMELEN]; /* Servers host */
char nettype[NETIDLEN]; /* Network type */
};
static struct rpc_call_private *rpc_call_private_main;
static void rpc_call_destroy __P((void *));
static void
rpc_call_destroy(void *vp)
{
register struct callrpc_private *crp = callrpc_private;
struct sockaddr_in server_addr;
enum clnt_stat clnt_stat;
struct hostent *hp;
struct timeval timeout, tottimeout;
struct rpc_call_private *rcp = (struct rpc_call_private *)vp;
if (crp == 0) {
crp = (struct callrpc_private *)calloc(1, sizeof (*crp));
if (crp == 0)
return (0);
callrpc_private = crp;
if (rcp) {
if (rcp->client)
CLNT_DESTROY(rcp->client);
free(rcp);
}
if (crp->oldhost == NULL) {
crp->oldhost = malloc(MAXHOSTNAMELEN);
crp->oldhost[0] = 0;
crp->socket = RPC_ANYSOCK;
}
if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum
&& strcmp(crp->oldhost, host) == 0) {
/* reuse old client */
}
/*
* This is the simplified interface to the client rpc layer.
* The client handle is not destroyed here and is reused for
* the future calls to same prog, vers, host and nettype combination.
*
* The total time available is 25 seconds.
*/
enum clnt_stat
rpc_call(host, prognum, versnum, procnum, inproc, in, outproc, out, nettype)
const char *host; /* host name */
rpcprog_t prognum; /* program number */
rpcvers_t versnum; /* version number */
rpcproc_t procnum; /* procedure number */
xdrproc_t inproc, outproc; /* in/out XDR procedures */
const char *in;
char *out; /* recv/send data */
const char *nettype; /* nettype */
{
struct rpc_call_private *rcp = (struct rpc_call_private *) 0;
enum clnt_stat clnt_stat;
struct timeval timeout, tottimeout;
static thread_key_t rpc_call_key;
extern mutex_t tsd_lock;
int main_thread = 1;
if ((main_thread = thr_main())) {
rcp = rpc_call_private_main;
} else {
crp->valid = 0;
if (crp->socket != -1)
(void)_close(crp->socket);
crp->socket = RPC_ANYSOCK;
if (crp->client) {
clnt_destroy(crp->client);
crp->client = NULL;
if (rpc_call_key == 0) {
mutex_lock(&tsd_lock);
if (rpc_call_key == 0)
thr_keycreate(&rpc_call_key, rpc_call_destroy);
mutex_unlock(&tsd_lock);
}
if ((hp = gethostbyname(host)) == NULL)
return ((int) RPC_UNKNOWNHOST);
rcp = (struct rpc_call_private *)thr_getspecific(rpc_call_key);
}
if (rcp == NULL) {
rcp = malloc(sizeof (*rcp));
if (rcp == NULL) {
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
return (rpc_createerr.cf_stat);
}
if (main_thread)
rpc_call_private_main = rcp;
else
thr_setspecific(rpc_call_key, (void *) rcp);
rcp->valid = 0;
rcp->client = NULL;
}
if ((nettype == NULL) || (nettype[0] == NULL))
nettype = "netpath";
if (!(rcp->valid && rcp->pid == getpid() &&
(rcp->prognum == prognum) &&
(rcp->versnum == versnum) &&
(!strcmp(rcp->host, host)) &&
(!strcmp(rcp->nettype, nettype)))) {
int fd;
rcp->valid = 0;
if (rcp->client)
CLNT_DESTROY(rcp->client);
/*
* Using the first successful transport for that type
*/
rcp->client = clnt_create(host, prognum, versnum, nettype);
rcp->pid = getpid();
if (rcp->client == NULL) {
return (rpc_createerr.cf_stat);
}
/*
* Set time outs for connectionless case. Do it
* unconditionally. Faster than doing a t_getinfo()
* and then doing the right thing.
*/
timeout.tv_usec = 0;
timeout.tv_sec = 5;
memset(&server_addr, 0, sizeof(server_addr));
memcpy((char *)&server_addr.sin_addr, hp->h_addr, hp->h_length);
server_addr.sin_len = sizeof(struct sockaddr_in);
server_addr.sin_family = AF_INET;
server_addr.sin_port = 0;
if ((crp->client = clntudp_create(&server_addr, (u_long)prognum,
(u_long)versnum, timeout, &crp->socket)) == NULL)
return ((int) rpc_createerr.cf_stat);
crp->valid = 1;
crp->oldprognum = prognum;
crp->oldversnum = versnum;
(void) strcpy(crp->oldhost, host);
}
(void) CLNT_CONTROL(rcp->client,
CLSET_RETRY_TIMEOUT, (char *)(void *)&timeout);
if (CLNT_CONTROL(rcp->client, CLGET_FD, (char *)(void *)&fd))
_fcntl(fd, F_SETFD, 1); /* make it "close on exec" */
rcp->prognum = prognum;
rcp->versnum = versnum;
if ((strlen(host) < (size_t)MAXHOSTNAMELEN) &&
(strlen(nettype) < (size_t)NETIDLEN)) {
(void) strcpy(rcp->host, host);
(void) strcpy(rcp->nettype, nettype);
rcp->valid = 1;
} else {
rcp->valid = 0;
}
} /* else reuse old client */
tottimeout.tv_sec = 25;
tottimeout.tv_usec = 0;
clnt_stat = clnt_call(crp->client, procnum, inproc, in,
/*LINTED const castaway*/
clnt_stat = CLNT_CALL(rcp->client, procnum, inproc, (char *) in,
outproc, out, tottimeout);
/*
* if call failed, empty cache
*/
if (clnt_stat != RPC_SUCCESS)
crp->valid = 0;
return ((int) clnt_stat);
rcp->valid = 0;
return (clnt_stat);
}

View File

@ -1,582 +0,0 @@
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC";*/
static char *rcsid = "$FreeBSD$";
#endif
/*
* clnt_tcp.c, Implements a TCP/IP based, client side RPC.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*
* TCP based RPC supports 'batched calls'.
* A sequence of calls may be batched-up in a send buffer. The rpc call
* return immediately to the client even though the call was not necessarily
* sent. The batching occurs if the results' xdr routine is NULL (0) AND
* the rpc timeout value is zero (see clnt.h, rpc).
*
* Clients should NOT casually batch calls that in fact return results; that is,
* the server side should be aware that a call is batched and not produce any
* return message. Batched calls that produce many result messages can
* deadlock (netlock) the client and the server....
*
* Now go hang yourself.
*/
#include "namespace.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <netdb.h>
#include <errno.h>
#include <rpc/pmap_clnt.h>
#include "un-namespace.h"
#define MCALL_MSG_SIZE 24
static int readtcp();
static int writetcp();
static enum clnt_stat clnttcp_call();
static void clnttcp_abort();
static void clnttcp_geterr();
static bool_t clnttcp_freeres();
static bool_t clnttcp_control();
static void clnttcp_destroy();
static struct clnt_ops tcp_ops = {
clnttcp_call,
clnttcp_abort,
clnttcp_geterr,
clnttcp_freeres,
clnttcp_destroy,
clnttcp_control
};
struct ct_data {
int ct_sock;
bool_t ct_closeit;
struct timeval ct_wait;
bool_t ct_waitset; /* wait set by clnt_control? */
struct sockaddr_in ct_addr;
struct rpc_err ct_error;
char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */
u_int ct_mpos; /* pos after marshal */
XDR ct_xdrs;
};
/*
* Create a client handle for a tcp/ip connection.
* If *sockp<0, *sockp is set to a newly created TCP socket and it is
* connected to raddr. If *sockp non-negative then
* raddr is ignored. The rpc/tcp package does buffering
* similar to stdio, so the client must pick send and receive buffer sizes,];
* 0 => use the default.
* If raddr->sin_port is 0, then a binder on the remote machine is
* consulted for the right port number.
* NB: *sockp is copied into a private area.
* NB: It is the clients responsibility to close *sockp.
* NB: The rpch->cl_auth is set null authentication. Caller may wish to set this
* something more useful.
*/
CLIENT *
clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
struct sockaddr_in *raddr;
u_long prog;
u_long vers;
register int *sockp;
u_int sendsz;
u_int recvsz;
{
CLIENT *h;
register struct ct_data *ct = NULL;
struct timeval now;
struct rpc_msg call_msg;
static u_int32_t disrupt;
if (disrupt == 0)
disrupt = (u_int32_t)(long)raddr;
h = (CLIENT *)mem_alloc(sizeof(*h));
if (h == NULL) {
(void)fprintf(stderr, "clnttcp_create: out of memory\n");
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
goto fooy;
}
ct = (struct ct_data *)mem_alloc(sizeof(*ct));
if (ct == NULL) {
(void)fprintf(stderr, "clnttcp_create: out of memory\n");
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
goto fooy;
}
/*
* If no port number given ask the pmap for one
*/
if (raddr->sin_port == 0) {
u_short port;
if ((port = pmap_getport(raddr, prog, vers, IPPROTO_TCP)) == 0) {
mem_free((caddr_t)ct, sizeof(struct ct_data));
mem_free((caddr_t)h, sizeof(CLIENT));
return ((CLIENT *)NULL);
}
raddr->sin_port = htons(port);
}
/*
* If no socket given, open one
*/
if (*sockp < 0) {
*sockp = _socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
(void)bindresvport(*sockp, (struct sockaddr_in *)0);
if ((*sockp < 0)
|| (_connect(*sockp, (struct sockaddr *)raddr,
sizeof(*raddr)) < 0)) {
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
if (*sockp != -1)
(void)_close(*sockp);
goto fooy;
}
ct->ct_closeit = TRUE;
} else {
ct->ct_closeit = FALSE;
}
/*
* Set up private data struct
*/
ct->ct_sock = *sockp;
ct->ct_wait.tv_usec = 0;
ct->ct_waitset = FALSE;
ct->ct_addr = *raddr;
/*
* Initialize call message
*/
(void)gettimeofday(&now, (struct timezone *)0);
call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec;
call_msg.rm_direction = CALL;
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
call_msg.rm_call.cb_prog = prog;
call_msg.rm_call.cb_vers = vers;
/*
* pre-serialize the static part of the call msg and stash it away
*/
xdrmem_create(&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE,
XDR_ENCODE);
if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) {
if (ct->ct_closeit) {
(void)_close(*sockp);
}
goto fooy;
}
ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
XDR_DESTROY(&(ct->ct_xdrs));
/*
* Create a client handle which uses xdrrec for serialization
* and authnone for authentication.
*/
xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz,
(caddr_t)ct, readtcp, writetcp);
h->cl_ops = &tcp_ops;
h->cl_private = (caddr_t) ct;
h->cl_auth = authnone_create();
return (h);
fooy:
/*
* Something goofed, free stuff and barf
*/
if (ct)
mem_free((caddr_t)ct, sizeof(struct ct_data));
if (h)
mem_free((caddr_t)h, sizeof(CLIENT));
return ((CLIENT *)NULL);
}
static enum clnt_stat
clnttcp_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
register CLIENT *h;
u_long proc;
xdrproc_t xdr_args;
caddr_t args_ptr;
xdrproc_t xdr_results;
caddr_t results_ptr;
struct timeval timeout;
{
register struct ct_data *ct = (struct ct_data *) h->cl_private;
register XDR *xdrs = &(ct->ct_xdrs);
struct rpc_msg reply_msg;
u_long x_id;
u_int32_t *msg_x_id = (u_int32_t *)(ct->ct_mcall); /* yuk */
register bool_t shipnow;
int refreshes = 2;
if (!ct->ct_waitset) {
ct->ct_wait = timeout;
}
shipnow =
(xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0
&& timeout.tv_usec == 0) ? FALSE : TRUE;
call_again:
xdrs->x_op = XDR_ENCODE;
ct->ct_error.re_status = RPC_SUCCESS;
x_id = ntohl(--(*msg_x_id));
if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) ||
(! XDR_PUTLONG(xdrs, (long *)&proc)) ||
(! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
(! (*xdr_args)(xdrs, args_ptr))) {
if (ct->ct_error.re_status == RPC_SUCCESS)
ct->ct_error.re_status = RPC_CANTENCODEARGS;
(void)xdrrec_endofrecord(xdrs, TRUE);
return (ct->ct_error.re_status);
}
if (! xdrrec_endofrecord(xdrs, shipnow))
return (ct->ct_error.re_status = RPC_CANTSEND);
if (! shipnow)
return (RPC_SUCCESS);
/*
* Hack to provide rpc-based message passing
*/
if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
return(ct->ct_error.re_status = RPC_TIMEDOUT);
}
/*
* Keep receiving until we get a valid transaction id
*/
xdrs->x_op = XDR_DECODE;
while (TRUE) {
reply_msg.acpted_rply.ar_verf = _null_auth;
reply_msg.acpted_rply.ar_results.where = NULL;
reply_msg.acpted_rply.ar_results.proc = xdr_void;
if (! xdrrec_skiprecord(xdrs))
return (ct->ct_error.re_status);
/* now decode and validate the response header */
if (! xdr_replymsg(xdrs, &reply_msg)) {
if (ct->ct_error.re_status == RPC_SUCCESS)
continue;
return (ct->ct_error.re_status);
}
if (reply_msg.rm_xid == x_id)
break;
}
/*
* process header
*/
_seterr_reply(&reply_msg, &(ct->ct_error));
if (ct->ct_error.re_status == RPC_SUCCESS) {
if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) {
ct->ct_error.re_status = RPC_AUTHERROR;
ct->ct_error.re_why = AUTH_INVALIDRESP;
} else if (! (*xdr_results)(xdrs, results_ptr)) {
if (ct->ct_error.re_status == RPC_SUCCESS)
ct->ct_error.re_status = RPC_CANTDECODERES;
}
/* free verifier ... */
if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
xdrs->x_op = XDR_FREE;
(void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf));
}
} /* end successful completion */
else {
/* maybe our credentials need to be refreshed ... */
if (refreshes-- && AUTH_REFRESH(h->cl_auth))
goto call_again;
} /* end of unsuccessful completion */
return (ct->ct_error.re_status);
}
static void
clnttcp_geterr(h, errp)
CLIENT *h;
struct rpc_err *errp;
{
register struct ct_data *ct =
(struct ct_data *) h->cl_private;
*errp = ct->ct_error;
}
static bool_t
clnttcp_freeres(cl, xdr_res, res_ptr)
CLIENT *cl;
xdrproc_t xdr_res;
caddr_t res_ptr;
{
register struct ct_data *ct = (struct ct_data *)cl->cl_private;
register XDR *xdrs = &(ct->ct_xdrs);
xdrs->x_op = XDR_FREE;
return ((*xdr_res)(xdrs, res_ptr));
}
static void
clnttcp_abort()
{
}
static bool_t
clnttcp_control(cl, request, info)
CLIENT *cl;
int request;
char *info;
{
register struct ct_data *ct = (struct ct_data *)cl->cl_private;
register struct timeval *tv;
int len;
switch (request) {
case CLSET_FD_CLOSE:
ct->ct_closeit = TRUE;
break;
case CLSET_FD_NCLOSE:
ct->ct_closeit = FALSE;
break;
case CLSET_TIMEOUT:
if (info == NULL)
return(FALSE);
tv = (struct timeval *)info;
ct->ct_wait.tv_sec = tv->tv_sec;
ct->ct_wait.tv_usec = tv->tv_usec;
ct->ct_waitset = TRUE;
break;
case CLGET_TIMEOUT:
if (info == NULL)
return(FALSE);
*(struct timeval *)info = ct->ct_wait;
break;
case CLGET_SERVER_ADDR:
if (info == NULL)
return(FALSE);
*(struct sockaddr_in *)info = ct->ct_addr;
break;
case CLGET_FD:
if (info == NULL)
return(FALSE);
*(int *)info = ct->ct_sock;
break;
case CLGET_XID:
/*
* use the knowledge that xid is the
* first element in the call structure *.
* This will get the xid of the PREVIOUS call
*/
if (info == NULL)
return(FALSE);
*(u_long *)info = ntohl(*(u_long *)ct->ct_mcall);
break;
case CLSET_XID:
/* This will set the xid of the NEXT call */
if (info == NULL)
return(FALSE);
*(u_long *)ct->ct_mcall = htonl(*(u_long *)info - 1);
/* decrement by 1 as clnttcp_call() increments once */
case CLGET_VERS:
/*
* This RELIES on the information that, in the call body,
* the version number field is the fifth field from the
* begining of the RPC header. MUST be changed if the
* call_struct is changed
*/
if (info == NULL)
return(FALSE);
*(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall +
4 * BYTES_PER_XDR_UNIT));
break;
case CLSET_VERS:
if (info == NULL)
return(FALSE);
*(u_long *)(ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT)
= htonl(*(u_long *)info);
break;
case CLGET_PROG:
/*
* This RELIES on the information that, in the call body,
* the program number field is the field from the
* begining of the RPC header. MUST be changed if the
* call_struct is changed
*/
if (info == NULL)
return(FALSE);
*(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall +
3 * BYTES_PER_XDR_UNIT));
break;
case CLSET_PROG:
if (info == NULL)
return(FALSE);
*(u_long *)(ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT)
= htonl(*(u_long *)info);
break;
case CLGET_LOCAL_ADDR:
len = sizeof(struct sockaddr);
if (_getsockname(ct->ct_sock, (struct sockaddr *)info, &len) <0)
return(FALSE);
break;
case CLGET_RETRY_TIMEOUT:
case CLSET_RETRY_TIMEOUT:
case CLGET_SVC_ADDR:
case CLSET_SVC_ADDR:
case CLSET_PUSH_TIMOD:
case CLSET_POP_TIMOD:
default:
return (FALSE);
}
return (TRUE);
}
static void
clnttcp_destroy(h)
CLIENT *h;
{
register struct ct_data *ct =
(struct ct_data *) h->cl_private;
if (ct->ct_closeit) {
(void)_close(ct->ct_sock);
}
XDR_DESTROY(&(ct->ct_xdrs));
mem_free((caddr_t)ct, sizeof(struct ct_data));
mem_free((caddr_t)h, sizeof(CLIENT));
}
/*
* Interface between xdr serializer and tcp connection.
* Behaves like the system calls, read & write, but keeps some error state
* around for the rpc level.
*/
static int
readtcp(ct, buf, len)
register struct ct_data *ct;
caddr_t buf;
register int len;
{
fd_set *fds, readfds;
struct timeval start, after, duration, delta, tmp, tv;
int r, save_errno;
if (len == 0)
return (0);
if (ct->ct_sock + 1 > FD_SETSIZE) {
int bytes = howmany(ct->ct_sock + 1, NFDBITS) * sizeof(fd_mask);
fds = (fd_set *)malloc(bytes);
if (fds == NULL)
return (-1);
memset(fds, 0, bytes);
} else {
fds = &readfds;
FD_ZERO(fds);
}
gettimeofday(&start, NULL);
delta = ct->ct_wait;
while (TRUE) {
/* XXX we know the other bits are still clear */
FD_SET(ct->ct_sock, fds);
tv = delta; /* in case select writes back */
r = _select(ct->ct_sock+1, fds, NULL, NULL, &tv);
save_errno = errno;
gettimeofday(&after, NULL);
timersub(&start, &after, &duration);
timersub(&ct->ct_wait, &duration, &tmp);
delta = tmp;
if (delta.tv_sec < 0 || !timerisset(&delta))
r = 0;
switch (r) {
case 0:
if (fds != &readfds)
free(fds);
ct->ct_error.re_status = RPC_TIMEDOUT;
return (-1);
case -1:
if (errno == EINTR)
continue;
if (fds != &readfds)
free(fds);
ct->ct_error.re_status = RPC_CANTRECV;
ct->ct_error.re_errno = save_errno;
return (-1);
}
break;
}
switch (len = _read(ct->ct_sock, buf, len)) {
case 0:
/* premature eof */
ct->ct_error.re_errno = ECONNRESET;
ct->ct_error.re_status = RPC_CANTRECV;
len = -1; /* it's really an error */
break;
case -1:
ct->ct_error.re_errno = errno;
ct->ct_error.re_status = RPC_CANTRECV;
break;
}
return (len);
}
static int
writetcp(ct, buf, len)
struct ct_data *ct;
caddr_t buf;
int len;
{
register int i, cnt;
for (cnt = len; cnt > 0; cnt -= i, buf += i) {
if ((i = _write(ct->ct_sock, buf, cnt)) == -1) {
ct->ct_error.re_errno = errno;
ct->ct_error.re_status = RPC_CANTSEND;
return (-1);
}
}
return (len);
}

View File

@ -1,569 +0,0 @@
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)clnt_udp.c 2.2 88/08/01 4.0 RPCSRC";*/
static char *rcsid = "$FreeBSD$";
#endif
/*
* clnt_udp.c, Implements a UDP/IP based, client side RPC.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*/
#include "namespace.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netdb.h>
#include <errno.h>
#include <rpc/pmap_clnt.h>
#include "un-namespace.h"
/*
* UDP bases client side rpc operations
*/
static enum clnt_stat clntudp_call();
static void clntudp_abort();
static void clntudp_geterr();
static bool_t clntudp_freeres();
static bool_t clntudp_control();
static void clntudp_destroy();
static struct clnt_ops udp_ops = {
clntudp_call,
clntudp_abort,
clntudp_geterr,
clntudp_freeres,
clntudp_destroy,
clntudp_control
};
/*
* Private data kept per client handle
*/
struct cu_data {
int cu_sock;
bool_t cu_closeit;
struct sockaddr_in cu_raddr;
int cu_rlen;
struct timeval cu_wait;
struct timeval cu_total;
struct rpc_err cu_error;
XDR cu_outxdrs;
u_int cu_xdrpos;
u_int cu_sendsz;
char *cu_outbuf;
u_int cu_recvsz;
char cu_inbuf[1];
};
/*
* Create a UDP based client handle.
* If *sockp<0, *sockp is set to a newly created UPD socket.
* If raddr->sin_port is 0 a binder on the remote machine
* is consulted for the correct port number.
* NB: It is the clients responsibility to close *sockp.
* NB: The rpch->cl_auth is initialized to null authentication.
* Caller may wish to set this something more useful.
*
* wait is the amount of time used between retransmitting a call if
* no response has been heard; retransmition occurs until the actual
* rpc call times out.
*
* sendsz and recvsz are the maximum allowable packet sizes that can be
* sent and received.
*/
CLIENT *
clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
struct sockaddr_in *raddr;
u_long program;
u_long version;
struct timeval wait;
register int *sockp;
u_int sendsz;
u_int recvsz;
{
CLIENT *cl;
register struct cu_data *cu = NULL;
struct timeval now;
struct rpc_msg call_msg;
static u_int32_t disrupt;
if (disrupt == 0)
disrupt = (u_int32_t)(long)raddr;
cl = (CLIENT *)mem_alloc(sizeof(CLIENT));
if (cl == NULL) {
(void) fprintf(stderr, "clntudp_create: out of memory\n");
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
goto fooy;
}
sendsz = ((sendsz + 3) / 4) * 4;
recvsz = ((recvsz + 3) / 4) * 4;
cu = (struct cu_data *)mem_alloc(sizeof(*cu) + sendsz + recvsz);
if (cu == NULL) {
(void) fprintf(stderr, "clntudp_create: out of memory\n");
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
goto fooy;
}
cu->cu_outbuf = &cu->cu_inbuf[recvsz];
(void)gettimeofday(&now, (struct timezone *)0);
if (raddr->sin_port == 0) {
u_short port;
if ((port =
pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) {
goto fooy;
}
raddr->sin_port = htons(port);
}
cl->cl_ops = &udp_ops;
cl->cl_private = (caddr_t)cu;
cu->cu_raddr = *raddr;
cu->cu_rlen = sizeof (cu->cu_raddr);
cu->cu_wait = wait;
cu->cu_total.tv_sec = -1;
cu->cu_total.tv_usec = -1;
cu->cu_sendsz = sendsz;
cu->cu_recvsz = recvsz;
call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec;
call_msg.rm_direction = CALL;
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
call_msg.rm_call.cb_prog = program;
call_msg.rm_call.cb_vers = version;
xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf,
sendsz, XDR_ENCODE);
if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) {
goto fooy;
}
cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));
if (*sockp < 0) {
int dontblock = 1;
*sockp = _socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (*sockp < 0) {
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
goto fooy;
}
/* attempt to bind to priv port */
(void)bindresvport(*sockp, (struct sockaddr_in *)0);
/* the sockets rpc controls are non-blocking */
(void)_ioctl(*sockp, FIONBIO, (char *) &dontblock);
cu->cu_closeit = TRUE;
} else {
cu->cu_closeit = FALSE;
}
cu->cu_sock = *sockp;
cl->cl_auth = authnone_create();
return (cl);
fooy:
if (cu)
mem_free((caddr_t)cu, sizeof(*cu) + sendsz + recvsz);
if (cl)
mem_free((caddr_t)cl, sizeof(CLIENT));
return ((CLIENT *)NULL);
}
CLIENT *
clntudp_create(raddr, program, version, wait, sockp)
struct sockaddr_in *raddr;
u_long program;
u_long version;
struct timeval wait;
register int *sockp;
{
return(clntudp_bufcreate(raddr, program, version, wait, sockp,
UDPMSGSIZE, UDPMSGSIZE));
}
static enum clnt_stat
clntudp_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
register CLIENT *cl; /* client handle */
u_long proc; /* procedure number */
xdrproc_t xargs; /* xdr routine for args */
caddr_t argsp; /* pointer to args */
xdrproc_t xresults; /* xdr routine for results */
caddr_t resultsp; /* pointer to results */
struct timeval utimeout; /* seconds to wait before giving up */
{
register struct cu_data *cu = (struct cu_data *)cl->cl_private;
register XDR *xdrs;
register int outlen;
register int inlen;
int fromlen;
fd_set *fds, readfds;
struct sockaddr_in from;
struct rpc_msg reply_msg;
XDR reply_xdrs;
struct timeval time_waited, start, after, tmp1, tmp2, tv;
bool_t ok;
int nrefreshes = 2; /* number of times to refresh cred */
struct timeval timeout;
if (cu->cu_total.tv_usec == -1)
timeout = utimeout; /* use supplied timeout */
else
timeout = cu->cu_total; /* use default timeout */
if (cu->cu_sock + 1 > FD_SETSIZE) {
int bytes = howmany(cu->cu_sock + 1, NFDBITS) * sizeof(fd_mask);
fds = (fd_set *)malloc(bytes);
if (fds == NULL)
return (cu->cu_error.re_status = RPC_CANTSEND);
memset(fds, 0, bytes);
} else {
fds = &readfds;
FD_ZERO(fds);
}
timerclear(&time_waited);
call_again:
xdrs = &(cu->cu_outxdrs);
xdrs->x_op = XDR_ENCODE;
XDR_SETPOS(xdrs, cu->cu_xdrpos);
/*
* the transaction is the first thing in the out buffer
*/
(*(u_short *)(cu->cu_outbuf))++;
if ((! XDR_PUTLONG(xdrs, (long *)&proc)) ||
(! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
(! (*xargs)(xdrs, argsp))) {
if (fds != &readfds)
free(fds);
return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
}
outlen = (int)XDR_GETPOS(xdrs);
send_again:
if (_sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0,
(struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen) != outlen) {
cu->cu_error.re_errno = errno;
if (fds != &readfds)
free(fds);
return (cu->cu_error.re_status = RPC_CANTSEND);
}
/*
* Hack to provide rpc-based message passing
*/
if (!timerisset(&timeout)) {
if (fds != &readfds)
free(fds);
return (cu->cu_error.re_status = RPC_TIMEDOUT);
}
/*
* sub-optimal code appears here because we have
* some clock time to spare while the packets are in flight.
* (We assume that this is actually only executed once.)
*/
reply_msg.acpted_rply.ar_verf = _null_auth;
reply_msg.acpted_rply.ar_results.where = resultsp;
reply_msg.acpted_rply.ar_results.proc = xresults;
gettimeofday(&start, NULL);
for (;;) {
/* XXX we know the other bits are still clear */
FD_SET(cu->cu_sock, fds);
tv = cu->cu_wait;
switch (_select(cu->cu_sock+1, fds, NULL, NULL, &tv)) {
case 0:
timeradd(&time_waited, &cu->cu_wait, &tmp1);
time_waited = tmp1;
if (timercmp(&time_waited, &timeout, <))
goto send_again;
if (fds != &readfds)
free(fds);
return (cu->cu_error.re_status = RPC_TIMEDOUT);
case -1:
if (errno == EINTR) {
gettimeofday(&after, NULL);
timersub(&after, &start, &tmp1);
timeradd(&time_waited, &tmp1, &tmp2);
time_waited = tmp2;
if (timercmp(&time_waited, &timeout, <))
continue;
if (fds != &readfds)
free(fds);
return (cu->cu_error.re_status = RPC_TIMEDOUT);
}
cu->cu_error.re_errno = errno;
if (fds != &readfds)
free(fds);
return (cu->cu_error.re_status = RPC_CANTRECV);
}
do {
fromlen = sizeof(struct sockaddr);
inlen = _recvfrom(cu->cu_sock, cu->cu_inbuf,
(int) cu->cu_recvsz, 0,
(struct sockaddr *)&from, &fromlen);
} while (inlen < 0 && errno == EINTR);
if (inlen < 0) {
if (errno == EWOULDBLOCK)
continue;
cu->cu_error.re_errno = errno;
if (fds != &readfds)
free(fds);
return (cu->cu_error.re_status = RPC_CANTRECV);
}
if (inlen < sizeof(u_int32_t))
continue;
/* see if reply transaction id matches sent id */
if (*((u_int32_t *)(cu->cu_inbuf)) != *((u_int32_t *)(cu->cu_outbuf)))
continue;
/* we now assume we have the proper reply */
break;
}
/*
* now decode and validate the response
*/
xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int)inlen, XDR_DECODE);
ok = xdr_replymsg(&reply_xdrs, &reply_msg);
/* XDR_DESTROY(&reply_xdrs); save a few cycles on noop destroy */
if (ok) {
_seterr_reply(&reply_msg, &(cu->cu_error));
if (cu->cu_error.re_status == RPC_SUCCESS) {
if (! AUTH_VALIDATE(cl->cl_auth,
&reply_msg.acpted_rply.ar_verf)) {
cu->cu_error.re_status = RPC_AUTHERROR;
cu->cu_error.re_why = AUTH_INVALIDRESP;
}
if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
xdrs->x_op = XDR_FREE;
(void)xdr_opaque_auth(xdrs,
&(reply_msg.acpted_rply.ar_verf));
}
} /* end successful completion */
else {
/* maybe our credentials need to be refreshed ... */
if (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth)) {
nrefreshes--;
goto call_again;
}
} /* end of unsuccessful completion */
} /* end of valid reply message */
else {
/*
* It's possible for xdr_replymsg() to fail partway
* through its attempt to decode the result from the
* server. If this happens, it will leave the reply
* structure partially populated with dynamically
* allocated memory. (This can happen if someone uses
* clntudp_bufcreate() to create a CLIENT handle and
* specifies a receive buffer size that is too small.)
* This memory must be free()ed to avoid a leak.
*/
int op = reply_xdrs.x_op;
reply_xdrs.x_op = XDR_FREE;
xdr_replymsg(&reply_xdrs, &reply_msg);
reply_xdrs.x_op = op;
cu->cu_error.re_status = RPC_CANTDECODERES;
}
if (fds != &readfds)
free(fds);
return (cu->cu_error.re_status);
}
static void
clntudp_geterr(cl, errp)
CLIENT *cl;
struct rpc_err *errp;
{
register struct cu_data *cu = (struct cu_data *)cl->cl_private;
*errp = cu->cu_error;
}
static bool_t
clntudp_freeres(cl, xdr_res, res_ptr)
CLIENT *cl;
xdrproc_t xdr_res;
caddr_t res_ptr;
{
register struct cu_data *cu = (struct cu_data *)cl->cl_private;
register XDR *xdrs = &(cu->cu_outxdrs);
xdrs->x_op = XDR_FREE;
return ((*xdr_res)(xdrs, res_ptr));
}
static void
clntudp_abort(/*h*/)
/*CLIENT *h;*/
{
}
static bool_t
clntudp_control(cl, request, info)
CLIENT *cl;
int request;
char *info;
{
register struct cu_data *cu = (struct cu_data *)cl->cl_private;
register struct timeval *tv;
int len;
switch (request) {
case CLSET_FD_CLOSE:
cu->cu_closeit = TRUE;
break;
case CLSET_FD_NCLOSE:
cu->cu_closeit = FALSE;
break;
case CLSET_TIMEOUT:
if (info == NULL)
return(FALSE);
tv = (struct timeval *)info;
cu->cu_total.tv_sec = tv->tv_sec;
cu->cu_total.tv_usec = tv->tv_usec;
break;
case CLGET_TIMEOUT:
if (info == NULL)
return(FALSE);
*(struct timeval *)info = cu->cu_total;
break;
case CLSET_RETRY_TIMEOUT:
if (info == NULL)
return(FALSE);
tv = (struct timeval *)info;
cu->cu_wait.tv_sec = tv->tv_sec;
cu->cu_wait.tv_usec = tv->tv_usec;
break;
case CLGET_RETRY_TIMEOUT:
if (info == NULL)
return(FALSE);
*(struct timeval *)info = cu->cu_wait;
break;
case CLGET_SERVER_ADDR:
if (info == NULL)
return(FALSE);
*(struct sockaddr_in *)info = cu->cu_raddr;
break;
case CLGET_FD:
if (info == NULL)
return(FALSE);
*(int *)info = cu->cu_sock;
break;
case CLGET_XID:
/*
* use the knowledge that xid is the
* first element in the call structure *.
* This will get the xid of the PREVIOUS call
*/
if (info == NULL)
return(FALSE);
*(u_long *)info = ntohl(*(u_long *)cu->cu_outbuf);
break;
case CLSET_XID:
/* This will set the xid of the NEXT call */
if (info == NULL)
return(FALSE);
*(u_long *)cu->cu_outbuf = htonl(*(u_long *)info - 1);
/* decrement by 1 as clntudp_call() increments once */
case CLGET_VERS:
/*
* This RELIES on the information that, in the call body,
* the version number field is the fifth field from the
* begining of the RPC header. MUST be changed if the
* call_struct is changed
*/
if (info == NULL)
return(FALSE);
*(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf +
4 * BYTES_PER_XDR_UNIT));
break;
case CLSET_VERS:
if (info == NULL)
return(FALSE);
*(u_long *)(cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT)
= htonl(*(u_long *)info);
break;
case CLGET_PROG:
/*
* This RELIES on the information that, in the call body,
* the program number field is the field from the
* begining of the RPC header. MUST be changed if the
* call_struct is changed
*/
if (info == NULL)
return(FALSE);
*(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf +
3 * BYTES_PER_XDR_UNIT));
break;
case CLSET_PROG:
if (info == NULL)
return(FALSE);
*(u_long *)(cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT)
= htonl(*(u_long *)info);
break;
case CLGET_LOCAL_ADDR:
len = sizeof(struct sockaddr);
if (_getsockname(cu->cu_sock, (struct sockaddr *)info, &len) <0)
return(FALSE);
break;
case CLGET_SVC_ADDR:
case CLSET_SVC_ADDR:
case CLSET_PUSH_TIMOD:
case CLSET_POP_TIMOD:
default:
return (FALSE);
}
return (TRUE);
}
static void
clntudp_destroy(cl)
CLIENT *cl;
{
register struct cu_data *cu = (struct cu_data *)cl->cl_private;
if (cu->cu_closeit) {
(void)_close(cu->cu_sock);
}
XDR_DESTROY(&(cu->cu_outxdrs));
mem_free((caddr_t)cu, (sizeof(*cu) + cu->cu_sendsz + cu->cu_recvsz));
mem_free((caddr_t)cl, sizeof(CLIENT));
}

View File

@ -1,637 +0,0 @@
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)clnt_unix.c 1.37 87/10/05 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)clnt_unix.c 2.2 88/08/01 4.0 RPCSRC";*/
static char *rcsid = "$FreeBSD$";
#endif
/*
* clnt_unix.c, Implements a AF_UNIX based, client side RPC.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*
* AF_UNIX based RPC supports 'batched calls'.
* A sequence of calls may be batched-up in a send buffer. The rpc call
* return immediately to the client even though the call was not necessarily
* sent. The batching occurs if the results' xdr routine is NULL (0) AND
* the rpc timeout value is zero (see clnt.h, rpc).
*
* Clients should NOT casually batch calls that in fact return results; that is,
* the server side should be aware that a call is batched and not produce any
* return message. Batched calls that produce many result messages can
* deadlock (netlock) the client and the server....
*
* Now go hang yourself.
*/
#include "namespace.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <rpc/rpc.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netdb.h>
#include <errno.h>
#include <rpc/pmap_clnt.h>
#include "un-namespace.h"
#define MCALL_MSG_SIZE 24
static int readunix();
static int writeunix();
static enum clnt_stat clntunix_call();
static void clntunix_abort();
static void clntunix_geterr();
static bool_t clntunix_freeres();
static bool_t clntunix_control();
static void clntunix_destroy();
static struct clnt_ops unix_ops = {
clntunix_call,
clntunix_abort,
clntunix_geterr,
clntunix_freeres,
clntunix_destroy,
clntunix_control
};
struct ct_data {
int ct_sock;
bool_t ct_closeit;
struct timeval ct_wait;
bool_t ct_waitset; /* wait set by clnt_control? */
struct sockaddr_un ct_addr;
struct rpc_err ct_error;
char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */
u_int ct_mpos; /* pos after marshal */
XDR ct_xdrs;
};
/*
* Create a client handle for a unix/ip connection.
* If *sockp<0, *sockp is set to a newly created TCP socket and it is
* connected to raddr. If *sockp non-negative then
* raddr is ignored. The rpc/unix package does buffering
* similar to stdio, so the client must pick send and receive buffer sizes,];
* 0 => use the default.
* If raddr->sin_port is 0, then a binder on the remote machine is
* consulted for the right port number.
* NB: *sockp is copied into a private area.
* NB: It is the clients responsibility to close *sockp.
* NB: The rpch->cl_auth is set null authentication. Caller may wish to set this
* something more useful.
*/
CLIENT *
clntunix_create(raddr, prog, vers, sockp, sendsz, recvsz)
struct sockaddr_un *raddr;
u_long prog;
u_long vers;
register int *sockp;
u_int sendsz;
u_int recvsz;
{
CLIENT *h;
register struct ct_data *ct = NULL;
struct timeval now;
struct rpc_msg call_msg;
static u_int32_t disrupt;
int len;
if (disrupt == 0)
disrupt = (u_int32_t)(long)raddr;
h = (CLIENT *)mem_alloc(sizeof(*h));
if (h == NULL) {
(void)fprintf(stderr, "clntunix_create: out of memory\n");
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
goto fooy;
}
ct = (struct ct_data *)mem_alloc(sizeof(*ct));
if (ct == NULL) {
(void)fprintf(stderr, "clntunix_create: out of memory\n");
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
goto fooy;
}
/*
* If no socket given, open one
*/
if (*sockp < 0) {
*sockp = _socket(AF_UNIX, SOCK_STREAM, 0);
len = strlen(raddr->sun_path) + sizeof(raddr->sun_family) +
sizeof(raddr->sun_len) + 1;
raddr->sun_len = len;
if ((*sockp < 0)
|| (_connect(*sockp, (struct sockaddr *)raddr, len) < 0)) {
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
if (*sockp != -1)
(void)_close(*sockp);
goto fooy;
}
ct->ct_closeit = TRUE;
} else {
ct->ct_closeit = FALSE;
}
/*
* Set up private data struct
*/
ct->ct_sock = *sockp;
ct->ct_wait.tv_usec = 0;
ct->ct_waitset = FALSE;
ct->ct_addr = *raddr;
/*
* Initialize call message
*/
(void)gettimeofday(&now, (struct timezone *)0);
call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec;
call_msg.rm_direction = CALL;
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
call_msg.rm_call.cb_prog = prog;
call_msg.rm_call.cb_vers = vers;
/*
* pre-serialize the static part of the call msg and stash it away
*/
xdrmem_create(&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE,
XDR_ENCODE);
if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) {
if (ct->ct_closeit) {
(void)_close(*sockp);
}
goto fooy;
}
ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
XDR_DESTROY(&(ct->ct_xdrs));
/*
* Create a client handle which uses xdrrec for serialization
* and authnone for authentication.
*/
xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz,
(caddr_t)ct, readunix, writeunix);
h->cl_ops = &unix_ops;
h->cl_private = (caddr_t) ct;
h->cl_auth = authnone_create();
return (h);
fooy:
/*
* Something goofed, free stuff and barf
*/
if (ct)
mem_free((caddr_t)ct, sizeof(struct ct_data));
if (h)
mem_free((caddr_t)h, sizeof(CLIENT));
return ((CLIENT *)NULL);
}
static enum clnt_stat
clntunix_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
register CLIENT *h;
u_long proc;
xdrproc_t xdr_args;
caddr_t args_ptr;
xdrproc_t xdr_results;
caddr_t results_ptr;
struct timeval timeout;
{
register struct ct_data *ct = (struct ct_data *) h->cl_private;
register XDR *xdrs = &(ct->ct_xdrs);
struct rpc_msg reply_msg;
u_long x_id;
u_int32_t *msg_x_id = (u_int32_t *)(ct->ct_mcall); /* yuk */
register bool_t shipnow;
int refreshes = 2;
if (!ct->ct_waitset) {
ct->ct_wait = timeout;
}
shipnow =
(xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0
&& timeout.tv_usec == 0) ? FALSE : TRUE;
call_again:
xdrs->x_op = XDR_ENCODE;
ct->ct_error.re_status = RPC_SUCCESS;
x_id = ntohl(--(*msg_x_id));
if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) ||
(! XDR_PUTLONG(xdrs, (long *)&proc)) ||
(! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
(! (*xdr_args)(xdrs, args_ptr))) {
if (ct->ct_error.re_status == RPC_SUCCESS)
ct->ct_error.re_status = RPC_CANTENCODEARGS;
(void)xdrrec_endofrecord(xdrs, TRUE);
return (ct->ct_error.re_status);
}
if (! xdrrec_endofrecord(xdrs, shipnow))
return (ct->ct_error.re_status = RPC_CANTSEND);
if (! shipnow)
return (RPC_SUCCESS);
/*
* Hack to provide rpc-based message passing
*/
if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
return(ct->ct_error.re_status = RPC_TIMEDOUT);
}
/*
* Keep receiving until we get a valid transaction id
*/
xdrs->x_op = XDR_DECODE;
while (TRUE) {
reply_msg.acpted_rply.ar_verf = _null_auth;
reply_msg.acpted_rply.ar_results.where = NULL;
reply_msg.acpted_rply.ar_results.proc = xdr_void;
if (! xdrrec_skiprecord(xdrs))
return (ct->ct_error.re_status);
/* now decode and validate the response header */
if (! xdr_replymsg(xdrs, &reply_msg)) {
if (ct->ct_error.re_status == RPC_SUCCESS)
continue;
return (ct->ct_error.re_status);
}
if (reply_msg.rm_xid == x_id)
break;
}
/*
* process header
*/
_seterr_reply(&reply_msg, &(ct->ct_error));
if (ct->ct_error.re_status == RPC_SUCCESS) {
if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) {
ct->ct_error.re_status = RPC_AUTHERROR;
ct->ct_error.re_why = AUTH_INVALIDRESP;
} else if (! (*xdr_results)(xdrs, results_ptr)) {
if (ct->ct_error.re_status == RPC_SUCCESS)
ct->ct_error.re_status = RPC_CANTDECODERES;
}
/* free verifier ... */
if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
xdrs->x_op = XDR_FREE;
(void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf));
}
} /* end successful completion */
else {
/* maybe our credentials need to be refreshed ... */
if (refreshes-- && AUTH_REFRESH(h->cl_auth))
goto call_again;
} /* end of unsuccessful completion */
return (ct->ct_error.re_status);
}
static void
clntunix_geterr(h, errp)
CLIENT *h;
struct rpc_err *errp;
{
register struct ct_data *ct =
(struct ct_data *) h->cl_private;
*errp = ct->ct_error;
}
static bool_t
clntunix_freeres(cl, xdr_res, res_ptr)
CLIENT *cl;
xdrproc_t xdr_res;
caddr_t res_ptr;
{
register struct ct_data *ct = (struct ct_data *)cl->cl_private;
register XDR *xdrs = &(ct->ct_xdrs);
xdrs->x_op = XDR_FREE;
return ((*xdr_res)(xdrs, res_ptr));
}
static void
clntunix_abort()
{
}
static bool_t
clntunix_control(cl, request, info)
CLIENT *cl;
int request;
char *info;
{
register struct ct_data *ct = (struct ct_data *)cl->cl_private;
register struct timeval *tv;
int len;
switch (request) {
case CLSET_FD_CLOSE:
ct->ct_closeit = TRUE;
break;
case CLSET_FD_NCLOSE:
ct->ct_closeit = FALSE;
break;
case CLSET_TIMEOUT:
if (info == NULL)
return(FALSE);
tv = (struct timeval *)info;
ct->ct_wait.tv_sec = tv->tv_sec;
ct->ct_wait.tv_usec = tv->tv_usec;
ct->ct_waitset = TRUE;
break;
case CLGET_TIMEOUT:
if (info == NULL)
return(FALSE);
*(struct timeval *)info = ct->ct_wait;
break;
case CLGET_SERVER_ADDR:
if (info == NULL)
return(FALSE);
*(struct sockaddr_un *)info = ct->ct_addr;
break;
case CLGET_FD:
if (info == NULL)
return(FALSE);
*(int *)info = ct->ct_sock;
break;
case CLGET_XID:
/*
* use the knowledge that xid is the
* first element in the call structure *.
* This will get the xid of the PREVIOUS call
*/
if (info == NULL)
return(FALSE);
*(u_long *)info = ntohl(*(u_long *)ct->ct_mcall);
break;
case CLSET_XID:
/* This will set the xid of the NEXT call */
if (info == NULL)
return(FALSE);
*(u_long *)ct->ct_mcall = htonl(*(u_long *)info - 1);
/* decrement by 1 as clntunix_call() increments once */
case CLGET_VERS:
/*
* This RELIES on the information that, in the call body,
* the version number field is the fifth field from the
* begining of the RPC header. MUST be changed if the
* call_struct is changed
*/
if (info == NULL)
return(FALSE);
*(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall +
4 * BYTES_PER_XDR_UNIT));
break;
case CLSET_VERS:
if (info == NULL)
return(FALSE);
*(u_long *)(ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT)
= htonl(*(u_long *)info);
break;
case CLGET_PROG:
/*
* This RELIES on the information that, in the call body,
* the program number field is the field from the
* begining of the RPC header. MUST be changed if the
* call_struct is changed
*/
if (info == NULL)
return(FALSE);
*(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall +
3 * BYTES_PER_XDR_UNIT));
break;
case CLSET_PROG:
if (info == NULL)
return(FALSE);
*(u_long *)(ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT)
= htonl(*(u_long *)info);
break;
case CLGET_LOCAL_ADDR:
len = sizeof(struct sockaddr);
if (_getsockname(ct->ct_sock, (struct sockaddr *)info, &len) <0)
return(FALSE);
break;
case CLGET_RETRY_TIMEOUT:
case CLSET_RETRY_TIMEOUT:
case CLGET_SVC_ADDR:
case CLSET_SVC_ADDR:
case CLSET_PUSH_TIMOD:
case CLSET_POP_TIMOD:
default:
return (FALSE);
}
return (TRUE);
}
static void
clntunix_destroy(h)
CLIENT *h;
{
register struct ct_data *ct =
(struct ct_data *) h->cl_private;
if (ct->ct_closeit) {
(void)_close(ct->ct_sock);
}
XDR_DESTROY(&(ct->ct_xdrs));
mem_free((caddr_t)ct, sizeof(struct ct_data));
mem_free((caddr_t)h, sizeof(CLIENT));
}
/*
* _read() and _write() are replaced with _recvmsg()/_sendmsg() so that
* we can pass ancillary control data. In this case, the data constists
* of credential information which the kernel will fill in for us.
* XXX: This code is specific to FreeBSD and will not work on other
* platforms without the requisite kernel modifications.
*/
struct cmessage {
struct cmsghdr cmsg;
struct cmsgcred cmcred;
};
static int __msgread(sock, buf, cnt)
int sock;
void *buf;
size_t cnt;
{
struct iovec iov[1];
struct msghdr msg;
struct cmessage cm;
bzero((char *)&cm, sizeof(cm));
iov[0].iov_base = buf;
iov[0].iov_len = cnt;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = (caddr_t)&cm;
msg.msg_controllen = sizeof(struct cmessage);
msg.msg_flags = 0;
return(_recvmsg(sock, &msg, 0));
}
static int __msgwrite(sock, buf, cnt)
int sock;
void *buf;
size_t cnt;
{
struct iovec iov[1];
struct msghdr msg;
struct cmessage cm;
bzero((char *)&cm, sizeof(cm));
iov[0].iov_base = buf;
iov[0].iov_len = cnt;
cm.cmsg.cmsg_type = SCM_CREDS;
cm.cmsg.cmsg_level = SOL_SOCKET;
cm.cmsg.cmsg_len = sizeof(struct cmessage);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = (caddr_t)&cm;
msg.msg_controllen = sizeof(struct cmessage);
msg.msg_flags = 0;
return(_sendmsg(sock, &msg, 0));
}
/*
* Interface between xdr serializer and unix connection.
* Behaves like the system calls, read & write, but keeps some error state
* around for the rpc level.
*/
static int
readunix(ct, buf, len)
register struct ct_data *ct;
caddr_t buf;
register int len;
{
fd_set *fds, readfds;
struct timeval start, after, duration, delta, tmp, tv;
int r, save_errno;
if (len == 0)
return (0);
if (ct->ct_sock + 1 > FD_SETSIZE) {
int bytes = howmany(ct->ct_sock + 1, NFDBITS) * sizeof(fd_mask);
fds = (fd_set *)malloc(bytes);
if (fds == NULL)
return (-1);
memset(fds, 0, bytes);
} else {
fds = &readfds;
FD_ZERO(fds);
}
gettimeofday(&start, NULL);
delta = ct->ct_wait;
while (TRUE) {
/* XXX we know the other bits are still clear */
FD_SET(ct->ct_sock, fds);
tv = delta; /* in case select writes back */
r = _select(ct->ct_sock+1, fds, NULL, NULL, &tv);
save_errno = errno;
gettimeofday(&after, NULL);
timersub(&start, &after, &duration);
timersub(&delta, &duration, &tmp);
delta = tmp;
if (delta.tv_sec < 0 || !timerisset(&delta))
r = 0;
switch (r) {
case 0:
if (fds != &readfds)
free(fds);
ct->ct_error.re_status = RPC_TIMEDOUT;
return (-1);
case -1:
if (errno == EINTR)
continue;
if (fds != &readfds)
free(fds);
ct->ct_error.re_status = RPC_CANTRECV;
ct->ct_error.re_errno = save_errno;
return (-1);
}
break;
}
switch (len = __msgread(ct->ct_sock, buf, len)) {
case 0:
/* premature eof */
ct->ct_error.re_errno = ECONNRESET;
ct->ct_error.re_status = RPC_CANTRECV;
len = -1; /* it's really an error */
break;
case -1:
ct->ct_error.re_errno = errno;
ct->ct_error.re_status = RPC_CANTRECV;
break;
}
return (len);
}
static int
writeunix(ct, buf, len)
struct ct_data *ct;
caddr_t buf;
int len;
{
register int i, cnt;
for (cnt = len; cnt > 0; cnt -= i, buf += i) {
if ((i = __msgwrite(ct->ct_sock, buf, cnt)) == -1) {
ct->ct_error.re_errno = errno;
ct->ct_error.re_status = RPC_CANTSEND;
return (-1);
}
}
return (len);
}

839
lib/libc/rpc/clnt_vc.c Normal file
View File

@ -0,0 +1,839 @@
/* $NetBSD: clnt_vc.c,v 1.4 2000/07/14 08:40:42 fvdl Exp $ */
/* $FreeBSD$ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
static char *sccsid = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";
static char *sccsid = "@(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC";
static char sccsid[] = "@(#)clnt_vc.c 1.19 89/03/16 Copyr 1988 Sun Micro";
#endif
/*
* clnt_tcp.c, Implements a TCP/IP based, client side RPC.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*
* TCP based RPC supports 'batched calls'.
* A sequence of calls may be batched-up in a send buffer. The rpc call
* return immediately to the client even though the call was not necessarily
* sent. The batching occurs if the results' xdr routine is NULL (0) AND
* the rpc timeout value is zero (see clnt.h, rpc).
*
* Clients should NOT casually batch calls that in fact return results; that is,
* the server side should be aware that a call is batched and not produce any
* return message. Batched calls that produce many result messages can
* deadlock (netlock) the client and the server....
*
* Now go hang yourself.
*/
#include "reentrant.h"
#include "namespace.h"
#include <sys/types.h>
#include <sys/poll.h>
#include <sys/syslog.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/uio.h>
#include <assert.h>
#include <err.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <rpc/rpc.h>
#include "un-namespace.h"
#include "rpc_com.h"
#define MCALL_MSG_SIZE 24
static enum clnt_stat clnt_vc_call __P((CLIENT *, rpcproc_t, xdrproc_t, caddr_t,
xdrproc_t, caddr_t, struct timeval));
static void clnt_vc_geterr __P((CLIENT *, struct rpc_err *));
static bool_t clnt_vc_freeres __P((CLIENT *, xdrproc_t, caddr_t));
static void clnt_vc_abort __P((CLIENT *));
static bool_t clnt_vc_control __P((CLIENT *, u_int, char *));
static void clnt_vc_destroy __P((CLIENT *));
static struct clnt_ops *clnt_vc_ops __P((void));
static bool_t time_not_ok __P((struct timeval *));
static int read_vc __P((caddr_t, caddr_t, int));
static int write_vc __P((caddr_t, caddr_t, int));
static int __msgwrite(int, void *, size_t);
static int __msgread(int, void *, size_t);
struct ct_data {
int ct_fd; /* connection's fd */
bool_t ct_closeit; /* close it on destroy */
struct timeval ct_wait; /* wait interval in milliseconds */
bool_t ct_waitset; /* wait set by clnt_control? */
struct netbuf ct_addr; /* remote addr */
struct rpc_err ct_error;
union {
char ct_mcallc[MCALL_MSG_SIZE]; /* marshalled callmsg */
u_int32_t ct_mcalli;
} ct_u;
u_int ct_mpos; /* pos after marshal */
XDR ct_xdrs; /* XDR stream */
};
struct cmessage {
struct cmsghdr cmsg;
struct cmsgcred cmcred;
};
/*
* This machinery implements per-fd locks for MT-safety. It is not
* sufficient to do per-CLIENT handle locks for MT-safety because a
* user may create more than one CLIENT handle with the same fd behind
* it. Therfore, we allocate an array of flags (vc_fd_locks), protected
* by the clnt_fd_lock mutex, and an array (vc_cv) of condition variables
* similarly protected. Vc_fd_lock[fd] == 1 => a call is activte on some
* CLIENT handle created for that fd.
* The current implementation holds locks across the entire RPC and reply.
* Yes, this is silly, and as soon as this code is proven to work, this
* should be the first thing fixed. One step at a time.
*/
static int *vc_fd_locks;
extern mutex_t clnt_fd_lock;
static cond_t *vc_cv;
#define release_fd_lock(fd, mask) { \
mutex_lock(&clnt_fd_lock); \
if (__isthreaded) \
vc_fd_locks[fd] = 0; \
mutex_unlock(&clnt_fd_lock); \
thr_sigsetmask(SIG_SETMASK, &(mask), (sigset_t *) NULL); \
cond_signal(&vc_cv[fd]); \
}
static const char clnt_vc_errstr[] = "%s : %s";
static const char clnt_vc_str[] = "clnt_vc_create";
static const char clnt_read_vc_str[] = "read_vc";
static const char __no_mem_str[] = "out of memory";
/*
* Create a client handle for a connection.
* Default options are set, which the user can change using clnt_control()'s.
* The rpc/vc package does buffering similar to stdio, so the client
* must pick send and receive buffer sizes, 0 => use the default.
* NB: fd is copied into a private area.
* NB: The rpch->cl_auth is set null authentication. Caller may wish to
* set this something more useful.
*
* fd should be an open socket
*/
CLIENT *
clnt_vc_create(fd, raddr, prog, vers, sendsz, recvsz)
int fd; /* open file descriptor */
const struct netbuf *raddr; /* servers address */
rpcprog_t prog; /* program number */
rpcvers_t vers; /* version number */
u_int sendsz; /* buffer recv size */
u_int recvsz; /* buffer send size */
{
CLIENT *cl; /* client handle */
struct ct_data *ct = NULL; /* client handle */
struct timeval now;
struct rpc_msg call_msg;
static u_int32_t disrupt;
sigset_t mask;
sigset_t newmask;
struct sockaddr_storage ss;
socklen_t slen;
struct __rpc_sockinfo si;
if (disrupt == 0)
disrupt = (u_int32_t)(long)raddr;
cl = (CLIENT *)mem_alloc(sizeof (*cl));
ct = (struct ct_data *)mem_alloc(sizeof (*ct));
if ((cl == (CLIENT *)NULL) || (ct == (struct ct_data *)NULL)) {
(void) syslog(LOG_ERR, clnt_vc_errstr,
clnt_vc_str, __no_mem_str);
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
goto err;
}
ct->ct_addr.buf = NULL;
sigfillset(&newmask);
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
mutex_lock(&clnt_fd_lock);
if (vc_fd_locks == (int *) NULL) {
int cv_allocsz, fd_allocsz;
int dtbsize = __rpc_dtbsize();
fd_allocsz = dtbsize * sizeof (int);
vc_fd_locks = (int *) mem_alloc(fd_allocsz);
if (vc_fd_locks == (int *) NULL) {
mutex_unlock(&clnt_fd_lock);
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
goto err;
} else
memset(vc_fd_locks, '\0', fd_allocsz);
assert(vc_cv == (cond_t *) NULL);
cv_allocsz = dtbsize * sizeof (cond_t);
vc_cv = (cond_t *) mem_alloc(cv_allocsz);
if (vc_cv == (cond_t *) NULL) {
mem_free(vc_fd_locks, fd_allocsz);
vc_fd_locks = (int *) NULL;
mutex_unlock(&clnt_fd_lock);
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
goto err;
} else {
int i;
for (i = 0; i < dtbsize; i++)
cond_init(&vc_cv[i], 0, (void *) 0);
}
} else
assert(vc_cv != (cond_t *) NULL);
/*
* XXX - fvdl connecting while holding a mutex?
*/
slen = sizeof ss;
if (_getpeername(fd, (struct sockaddr *)(void *)&ss, &slen) < 0) {
if (errno != ENOTCONN) {
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
mutex_unlock(&clnt_fd_lock);
goto err;
}
if (_connect(fd, (struct sockaddr *)raddr->buf, raddr->len) < 0){
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
mutex_unlock(&clnt_fd_lock);
goto err;
}
}
mutex_unlock(&clnt_fd_lock);
if (!__rpc_fd2sockinfo(fd, &si))
goto err;
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
ct->ct_closeit = FALSE;
/*
* Set up private data struct
*/
ct->ct_fd = fd;
ct->ct_wait.tv_usec = 0;
ct->ct_waitset = FALSE;
ct->ct_addr.buf = malloc(raddr->maxlen);
if (ct->ct_addr.buf == NULL)
goto err;
memcpy(ct->ct_addr.buf, &raddr->buf, raddr->len);
ct->ct_addr.len = raddr->maxlen;
ct->ct_addr.maxlen = raddr->maxlen;
/*
* Initialize call message
*/
(void)gettimeofday(&now, NULL);
call_msg.rm_xid = ((u_int32_t)++disrupt) ^ __RPC_GETXID(&now);
call_msg.rm_direction = CALL;
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
call_msg.rm_call.cb_prog = (u_int32_t)prog;
call_msg.rm_call.cb_vers = (u_int32_t)vers;
/*
* pre-serialize the static part of the call msg and stash it away
*/
xdrmem_create(&(ct->ct_xdrs), ct->ct_u.ct_mcallc, MCALL_MSG_SIZE,
XDR_ENCODE);
if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) {
if (ct->ct_closeit) {
(void)_close(fd);
}
goto err;
}
ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
XDR_DESTROY(&(ct->ct_xdrs));
/*
* Create a client handle which uses xdrrec for serialization
* and authnone for authentication.
*/
cl->cl_ops = clnt_vc_ops();
cl->cl_private = ct;
cl->cl_auth = authnone_create();
sendsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsz);
recvsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsz);
xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz,
cl->cl_private, read_vc, write_vc);
return (cl);
err:
if (cl) {
if (ct) {
if (ct->ct_addr.len)
mem_free(ct->ct_addr.buf, ct->ct_addr.len);
mem_free((caddr_t)ct, sizeof (struct ct_data));
}
if (cl)
mem_free((caddr_t)cl, sizeof (CLIENT));
}
return ((CLIENT *)NULL);
}
static enum clnt_stat
clnt_vc_call(cl, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
CLIENT *cl;
rpcproc_t proc;
xdrproc_t xdr_args;
caddr_t args_ptr;
xdrproc_t xdr_results;
caddr_t results_ptr;
struct timeval timeout;
{
struct ct_data *ct = (struct ct_data *) cl->cl_private;
XDR *xdrs = &(ct->ct_xdrs);
struct rpc_msg reply_msg;
u_int32_t x_id;
u_int32_t *msg_x_id = &ct->ct_u.ct_mcalli; /* yuk */
bool_t shipnow;
int refreshes = 2;
sigset_t mask, newmask;
int rpc_lock_value;
assert(cl != NULL);
sigfillset(&newmask);
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
mutex_lock(&clnt_fd_lock);
while (vc_fd_locks[ct->ct_fd])
cond_wait(&vc_cv[ct->ct_fd], &clnt_fd_lock);
if (__isthreaded)
rpc_lock_value = 1;
else
rpc_lock_value = 0;
vc_fd_locks[ct->ct_fd] = rpc_lock_value;
mutex_unlock(&clnt_fd_lock);
if (!ct->ct_waitset) {
/* If time is not within limits, we ignore it. */
if (time_not_ok(&timeout) == FALSE)
ct->ct_wait = timeout;
}
shipnow =
(xdr_results == NULL && timeout.tv_sec == 0
&& timeout.tv_usec == 0) ? FALSE : TRUE;
call_again:
xdrs->x_op = XDR_ENCODE;
ct->ct_error.re_status = RPC_SUCCESS;
x_id = ntohl(--(*msg_x_id));
if ((! XDR_PUTBYTES(xdrs, ct->ct_u.ct_mcallc, ct->ct_mpos)) ||
(! XDR_PUTINT32(xdrs, &proc)) ||
(! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
(! (*xdr_args)(xdrs, args_ptr))) {
if (ct->ct_error.re_status == RPC_SUCCESS)
ct->ct_error.re_status = RPC_CANTENCODEARGS;
(void)xdrrec_endofrecord(xdrs, TRUE);
release_fd_lock(ct->ct_fd, mask);
return (ct->ct_error.re_status);
}
if (! xdrrec_endofrecord(xdrs, shipnow)) {
release_fd_lock(ct->ct_fd, mask);
return (ct->ct_error.re_status = RPC_CANTSEND);
}
if (! shipnow) {
release_fd_lock(ct->ct_fd, mask);
return (RPC_SUCCESS);
}
/*
* Hack to provide rpc-based message passing
*/
if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
release_fd_lock(ct->ct_fd, mask);
return(ct->ct_error.re_status = RPC_TIMEDOUT);
}
/*
* Keep receiving until we get a valid transaction id
*/
xdrs->x_op = XDR_DECODE;
while (TRUE) {
reply_msg.acpted_rply.ar_verf = _null_auth;
reply_msg.acpted_rply.ar_results.where = NULL;
reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
if (! xdrrec_skiprecord(xdrs)) {
release_fd_lock(ct->ct_fd, mask);
return (ct->ct_error.re_status);
}
/* now decode and validate the response header */
if (! xdr_replymsg(xdrs, &reply_msg)) {
if (ct->ct_error.re_status == RPC_SUCCESS)
continue;
release_fd_lock(ct->ct_fd, mask);
return (ct->ct_error.re_status);
}
if (reply_msg.rm_xid == x_id)
break;
}
/*
* process header
*/
_seterr_reply(&reply_msg, &(ct->ct_error));
if (ct->ct_error.re_status == RPC_SUCCESS) {
if (! AUTH_VALIDATE(cl->cl_auth,
&reply_msg.acpted_rply.ar_verf)) {
ct->ct_error.re_status = RPC_AUTHERROR;
ct->ct_error.re_why = AUTH_INVALIDRESP;
} else if (! (*xdr_results)(xdrs, results_ptr)) {
if (ct->ct_error.re_status == RPC_SUCCESS)
ct->ct_error.re_status = RPC_CANTDECODERES;
}
/* free verifier ... */
if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
xdrs->x_op = XDR_FREE;
(void)xdr_opaque_auth(xdrs,
&(reply_msg.acpted_rply.ar_verf));
}
} /* end successful completion */
else {
/* maybe our credentials need to be refreshed ... */
if (refreshes-- && AUTH_REFRESH(cl->cl_auth, &reply_msg))
goto call_again;
} /* end of unsuccessful completion */
release_fd_lock(ct->ct_fd, mask);
return (ct->ct_error.re_status);
}
static void
clnt_vc_geterr(cl, errp)
CLIENT *cl;
struct rpc_err *errp;
{
struct ct_data *ct;
assert(cl != NULL);
assert(errp != NULL);
ct = (struct ct_data *) cl->cl_private;
*errp = ct->ct_error;
}
static bool_t
clnt_vc_freeres(cl, xdr_res, res_ptr)
CLIENT *cl;
xdrproc_t xdr_res;
caddr_t res_ptr;
{
struct ct_data *ct;
XDR *xdrs;
bool_t dummy;
sigset_t mask;
sigset_t newmask;
assert(cl != NULL);
ct = (struct ct_data *)cl->cl_private;
xdrs = &(ct->ct_xdrs);
sigfillset(&newmask);
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
mutex_lock(&clnt_fd_lock);
while (vc_fd_locks[ct->ct_fd])
cond_wait(&vc_cv[ct->ct_fd], &clnt_fd_lock);
xdrs->x_op = XDR_FREE;
dummy = (*xdr_res)(xdrs, res_ptr);
mutex_unlock(&clnt_fd_lock);
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
cond_signal(&vc_cv[ct->ct_fd]);
return dummy;
}
/*ARGSUSED*/
static void
clnt_vc_abort(cl)
CLIENT *cl;
{
}
static bool_t
clnt_vc_control(cl, request, info)
CLIENT *cl;
u_int request;
char *info;
{
struct ct_data *ct;
void *infop = info;
sigset_t mask;
sigset_t newmask;
int rpc_lock_value;
assert(cl != NULL);
ct = (struct ct_data *)cl->cl_private;
sigfillset(&newmask);
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
mutex_lock(&clnt_fd_lock);
while (vc_fd_locks[ct->ct_fd])
cond_wait(&vc_cv[ct->ct_fd], &clnt_fd_lock);
if (__isthreaded)
rpc_lock_value = 1;
else
rpc_lock_value = 0;
vc_fd_locks[ct->ct_fd] = rpc_lock_value;
mutex_unlock(&clnt_fd_lock);
switch (request) {
case CLSET_FD_CLOSE:
ct->ct_closeit = TRUE;
release_fd_lock(ct->ct_fd, mask);
return (TRUE);
case CLSET_FD_NCLOSE:
ct->ct_closeit = FALSE;
release_fd_lock(ct->ct_fd, mask);
return (TRUE);
default:
break;
}
/* for other requests which use info */
if (info == NULL) {
release_fd_lock(ct->ct_fd, mask);
return (FALSE);
}
switch (request) {
case CLSET_TIMEOUT:
if (time_not_ok((struct timeval *)(void *)info)) {
release_fd_lock(ct->ct_fd, mask);
return (FALSE);
}
ct->ct_wait = *(struct timeval *)infop;
ct->ct_waitset = TRUE;
break;
case CLGET_TIMEOUT:
*(struct timeval *)infop = ct->ct_wait;
break;
case CLGET_SERVER_ADDR:
(void) memcpy(info, ct->ct_addr.buf, (size_t)ct->ct_addr.len);
break;
case CLGET_FD:
*(int *)(void *)info = ct->ct_fd;
break;
case CLGET_SVC_ADDR:
/* The caller should not free this memory area */
*(struct netbuf *)(void *)info = ct->ct_addr;
break;
case CLSET_SVC_ADDR: /* set to new address */
release_fd_lock(ct->ct_fd, mask);
return (FALSE);
case CLGET_XID:
/*
* use the knowledge that xid is the
* first element in the call structure
* This will get the xid of the PREVIOUS call
*/
*(u_int32_t *)(void *)info =
ntohl(*(u_int32_t *)(void *)&ct->ct_u.ct_mcalli);
break;
case CLSET_XID:
/* This will set the xid of the NEXT call */
*(u_int32_t *)(void *)&ct->ct_u.ct_mcalli =
htonl(*((u_int32_t *)(void *)info) + 1);
/* increment by 1 as clnt_vc_call() decrements once */
break;
case CLGET_VERS:
/*
* This RELIES on the information that, in the call body,
* the version number field is the fifth field from the
* begining of the RPC header. MUST be changed if the
* call_struct is changed
*/
*(u_int32_t *)(void *)info =
ntohl(*(u_int32_t *)(void *)(ct->ct_u.ct_mcallc +
4 * BYTES_PER_XDR_UNIT));
break;
case CLSET_VERS:
*(u_int32_t *)(void *)(ct->ct_u.ct_mcallc +
4 * BYTES_PER_XDR_UNIT) =
htonl(*(u_int32_t *)(void *)info);
break;
case CLGET_PROG:
/*
* This RELIES on the information that, in the call body,
* the program number field is the fourth field from the
* begining of the RPC header. MUST be changed if the
* call_struct is changed
*/
*(u_int32_t *)(void *)info =
ntohl(*(u_int32_t *)(void *)(ct->ct_u.ct_mcallc +
3 * BYTES_PER_XDR_UNIT));
break;
case CLSET_PROG:
*(u_int32_t *)(void *)(ct->ct_u.ct_mcallc +
3 * BYTES_PER_XDR_UNIT) =
htonl(*(u_int32_t *)(void *)info);
break;
default:
release_fd_lock(ct->ct_fd, mask);
return (FALSE);
}
release_fd_lock(ct->ct_fd, mask);
return (TRUE);
}
static void
clnt_vc_destroy(cl)
CLIENT *cl;
{
struct ct_data *ct = (struct ct_data *) cl->cl_private;
int ct_fd = ct->ct_fd;
sigset_t mask;
sigset_t newmask;
assert(cl != NULL);
ct = (struct ct_data *) cl->cl_private;
sigfillset(&newmask);
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
mutex_lock(&clnt_fd_lock);
while (vc_fd_locks[ct_fd])
cond_wait(&vc_cv[ct_fd], &clnt_fd_lock);
if (ct->ct_closeit && ct->ct_fd != -1) {
(void)_close(ct->ct_fd);
}
XDR_DESTROY(&(ct->ct_xdrs));
if (ct->ct_addr.buf)
free(ct->ct_addr.buf);
mem_free(ct, sizeof(struct ct_data));
mem_free(cl, sizeof(CLIENT));
mutex_unlock(&clnt_fd_lock);
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
cond_signal(&vc_cv[ct_fd]);
}
/*
* Interface between xdr serializer and tcp connection.
* Behaves like the system calls, read & write, but keeps some error state
* around for the rpc level.
*/
static int
read_vc(ctp, buf, len)
caddr_t ctp;
caddr_t buf;
int len;
{
struct sockaddr sa;
socklen_t sal;
struct ct_data *ct = (struct ct_data *)(void *)ctp;
struct pollfd fd;
int milliseconds = (int)((ct->ct_wait.tv_sec * 1000) +
(ct->ct_wait.tv_usec / 1000));
if (len == 0)
return (0);
fd.fd = ct->ct_fd;
fd.events = POLLIN;
for (;;) {
switch (_poll(&fd, 1, milliseconds)) {
case 0:
ct->ct_error.re_status = RPC_TIMEDOUT;
return (-1);
case -1:
if (errno == EINTR)
continue;
ct->ct_error.re_status = RPC_CANTRECV;
ct->ct_error.re_errno = errno;
return (-1);
}
break;
}
sal = sizeof(sa);
if ((_getpeername(ct->ct_fd, &sa, &sal) == 0) &&
(sa.sa_family == AF_LOCAL)) {
len = __msgread(ct->ct_fd, buf, (size_t)len);
} else {
len = _read(ct->ct_fd, buf, (size_t)len);
}
switch (len) {
case 0:
/* premature eof */
ct->ct_error.re_errno = ECONNRESET;
ct->ct_error.re_status = RPC_CANTRECV;
len = -1; /* it's really an error */
break;
case -1:
ct->ct_error.re_errno = errno;
ct->ct_error.re_status = RPC_CANTRECV;
break;
}
return (len);
}
static int
write_vc(ctp, buf, len)
caddr_t ctp;
caddr_t buf;
int len;
{
struct sockaddr sa;
socklen_t sal;
struct ct_data *ct = (struct ct_data *)(void *)ctp;
int i, cnt;
sal = sizeof(sa);
if ((_getpeername(ct->ct_fd, &sa, &sal) == 0) &&
(sa.sa_family == AF_LOCAL)) {
for (cnt = len; cnt > 0; cnt -= i, buf += i) {
if ((i = __msgwrite(ct->ct_fd, buf,
(size_t)cnt)) == -1) {
ct->ct_error.re_errno = errno;
ct->ct_error.re_status = RPC_CANTSEND;
return (-1);
}
}
} else {
for (cnt = len; cnt > 0; cnt -= i, buf += i) {
if ((i = _write(ct->ct_fd, buf, (size_t)cnt)) == -1) {
ct->ct_error.re_errno = errno;
ct->ct_error.re_status = RPC_CANTSEND;
return (-1);
}
}
}
return (len);
}
static struct clnt_ops *
clnt_vc_ops()
{
static struct clnt_ops ops;
extern mutex_t ops_lock;
sigset_t mask, newmask;
/* VARIABLES PROTECTED BY ops_lock: ops */
sigfillset(&newmask);
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
mutex_lock(&ops_lock);
if (ops.cl_call == NULL) {
ops.cl_call = clnt_vc_call;
ops.cl_abort = clnt_vc_abort;
ops.cl_geterr = clnt_vc_geterr;
ops.cl_freeres = clnt_vc_freeres;
ops.cl_destroy = clnt_vc_destroy;
ops.cl_control = clnt_vc_control;
}
mutex_unlock(&ops_lock);
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
return (&ops);
}
/*
* Make sure that the time is not garbage. -1 value is disallowed.
* Note this is different from time_not_ok in clnt_dg.c
*/
static bool_t
time_not_ok(t)
struct timeval *t;
{
return (t->tv_sec <= -1 || t->tv_sec > 100000000 ||
t->tv_usec <= -1 || t->tv_usec > 1000000);
}
__msgread(sock, buf, cnt)
int sock;
void *buf;
size_t cnt;
{
struct iovec iov[1];
struct msghdr msg;
struct cmessage cm;
bzero((char *)&cm, sizeof(cm));
iov[0].iov_base = buf;
iov[0].iov_len = cnt;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = (caddr_t)&cm;
msg.msg_controllen = sizeof(struct cmessage);
msg.msg_flags = 0;
return(_recvmsg(sock, &msg, 0));
}
static int
__msgwrite(sock, buf, cnt)
int sock;
void *buf;
size_t cnt;
{
struct iovec iov[1];
struct msghdr msg;
struct cmessage cm;
bzero((char *)&cm, sizeof(cm));
iov[0].iov_base = buf;
iov[0].iov_len = cnt;
cm.cmsg.cmsg_type = SCM_CREDS;
cm.cmsg.cmsg_level = SOL_SOCKET;
cm.cmsg.cmsg_len = sizeof(struct cmessage);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = (caddr_t)&cm;
msg.msg_controllen = sizeof(struct cmessage);
msg.msg_flags = 0;
return(_sendmsg(sock, &msg, 0));
}

View File

@ -28,15 +28,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include "namespace.h"
#include <sys/types.h>
#include <rpc/des_crypt.h>
#include <rpc/des.h>
#include <string.h>
#include <rpcsvc/crypt.h>
#include "un-namespace.h"
#ifndef lint
static const char rcsid[] = "$FreeBSD$";

View File

@ -1,114 +0,0 @@
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)get_myaddress.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *rcsid = "$FreeBSD$";
#endif
/*
* get_myaddress.c
*
* Get client's IP address via ioctl. This avoids using the yellowpages.
* Copyright (C) 1984, Sun Microsystems, Inc.
*/
#include "namespace.h"
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/pmap_prot.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "un-namespace.h"
/*
* don't use gethostbyname, which would invoke yellow pages
*
* Avoid loopback interfaces. We return information from a loopback
* interface only if there are no other possible interfaces.
*/
int
get_myaddress(addr)
struct sockaddr_in *addr;
{
int s;
char buf[BUFSIZ];
struct ifconf ifc;
struct ifreq ifreq, *ifr, *end;
int loopback = 0, gotit = 0;
if ((s = _socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
return(-1);
}
ifc.ifc_len = sizeof (buf);
ifc.ifc_buf = buf;
if (_ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
_close(s);
return(-1);
}
again:
ifr = ifc.ifc_req;
end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
while (ifr < end) {
memcpy(&ifreq, ifr, sizeof(ifreq));
if (_ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
_close(s);
return(-1);
}
if (((ifreq.ifr_flags & IFF_UP) &&
ifr->ifr_addr.sa_family == AF_INET &&
!(ifreq.ifr_flags & IFF_LOOPBACK)) ||
(loopback == 1 && (ifreq.ifr_flags & IFF_LOOPBACK)
&& (ifr->ifr_addr.sa_family == AF_INET)
&& (ifreq.ifr_flags & IFF_UP))) {
*addr = *((struct sockaddr_in *)&ifr->ifr_addr);
addr->sin_port = htons(PMAPPORT);
gotit = 1;
break;
}
if (ifr->ifr_addr.sa_len)
ifr = (struct ifreq *) ((caddr_t) ifr +
ifr->ifr_addr.sa_len -
sizeof(struct sockaddr));
ifr++;
}
if (gotit == 0 && loopback == 0) {
loopback = 1;
goto again;
}
(void)_close(s);
return (gotit ? 0 : -1);
}

182
lib/libc/rpc/getnetconfig.3 Normal file
View File

@ -0,0 +1,182 @@
.\" @(#)getnetconfig.3n 1.28 93/06/02 SMI; from SVr4
.\" $NetBSD: getnetconfig.3,v 1.1 2000/06/02 23:11:11 fvdl Exp $
.\" $FreeBSD$
.\" Copyright 1989 AT&T
.Dd April 22, 2000
.Dt GETNETCONFIG 3
.Os
.Sh NAME
.Nm getnetconfig ,
.Nm setnetconfig ,
.Nm endnetconfig ,
.Nm getnetconfigent ,
.Nm freenetconfigent ,
.Nm nc_perror ,
.Nm nc_sperror
.Nd get network configuration database entry
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.Fd #include <netconfig.h>
.Ft "struct netconfig *"
.Fn getnetconfig "void *handlep"
.Ft "void *"
.Fn setnetconfig "void"
.Ft int
.Fn endnetconfig "void *handlep"
.Ft "struct netconfig *"
.Fn getnetconfigent "const char *netid"
.Ft void
.Fn freenetconfigent "struct netconfig *netconfigp"
.Ft void
.Fn nc_perror "const char *msg"
.Ft "char *"
.Fn nc_sperror "void"
.Sh DESCRIPTION
The library routines described on this page
provide the application access to
the system network configuration database,
.Pa /etc/netconfig .
.Fn getnetconfig
returns a pointer to the
current entry in the
netconfig
database, formatted as a
.Ft "struct netconfig" .
Successive calls will return successive netconfig
entries in the netconfig database.
.Fn getnetconfig
can be used to search the entire netconfig
file.
.Fn getnetconfig
returns
.Dv NULL
at the end of the file.
.Fa handlep
is the handle obtained through
.Fn setnetconfig .
.Pp
A call to
.Fn setnetconfig
has the effect of
.Dq binding
to or
.Dq rewinding
the netconfig database.
.Fn setnetconfig
must be called before the first call to
.Fn getnetconfig
and may be called at any other time.
.Fn setnetconfig
need not be called before a call to
.Fn getnetconfigent .
.Fn setnetconfig
returns a unique handle to be used by
.Fn getnetconfig .
.Pp
.Fn endnetconfig
should be called when processing is complete to release resources for reuse.
.Fa handlep
is the handle obtained through
.Fn setnetconfig .
Programmers should be aware, however, that the last call to
.Fn endnetconfig
frees all memory allocated by
.Fn getnetconfig
for the
.Ft "struct netconfig"
data structure.
.Fn endnetconfig
may not be called before
.Fn setnetconfig .
.Pp
.Fn getnetconfigent
returns a pointer
to the netconfig structure corresponding
to
.Fa netid .
It returns
.Dv NULL
if
.Fa netid
is invalid
(that is, does not name an entry in the netconfig database).
.Pp
.Fn freenetconfigent
frees the netconfig structure pointed to by
.Fa netconfigp
(previously returned by
.Fn getnetconfigent ) .
.Pp
.Fn nc_perror
prints a message to the standard error indicating why any of the
above routines failed.
The message is prepended with the string
.Fa msg
and a colon.
A newline character is appended at the end of the message.
.Pp
.Fn nc_sperror
is similar to
.Fn nc_perror
but instead of sending the message
to the standard error, will return a pointer to a string that
contains the error message.
.Pp
.Fn nc_perror
and
.Fn nc_sperror
can also be used with the
.Ev NETPATH
access routines defined in
.Xr getnetpath 3 .
.Sh RETURN VALUES
.Fn setnetconfig
returns a unique handle to be used by
.Fn getnetconfig .
In the case of an error,
.Fn setnetconfig
returns
.Dv NULL
and
.Fn nc_perror
or
.Fn nc_sperror
can be used to print the reason for failure.
.Pp
.Fn getnetconfig
returns a pointer to the current entry in the netconfig
database, formatted as a
.Ft "struct netconfig" .
.Fn getnetconfig
returns
.Dv NULL
at the end of the file, or upon failure.
.Pp
.Fn endnetconfig
returns 0 on success and \-1 on failure
(for example, if
.Fn setnetconfig
was not called previously).
.Pp
On success,
.Fn getnetconfigent
returns a pointer to the
.Ft "struct netconfig"
structure corresponding to
.Fa netid ;
otherwise it returns
.Dv NULL .
.Pp
.Fn nc_sperror
returns a pointer to a buffer which contains the error message string.
This buffer is overwritten on each call.
In multithreaded applications, this buffer is
implemented as thread-specific data.
.Sh FILES
.Bl -tag -width /etc/netconfig -compact
.It Pa /etc/netconfig
.El
.Sh SEE ALSO
.Xr getnetpath 3 ,
.Xr netconfig 5

674
lib/libc/rpc/getnetconfig.c Normal file
View File

@ -0,0 +1,674 @@
/* $NetBSD: getnetconfig.c,v 1.3 2000/07/06 03:10:34 christos Exp $ */
/* $FreeBSD$ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user or with the express written consent of
* Sun Microsystems, Inc.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
#ifndef lint
static char sccsid[] = "@(#)getnetconfig.c 1.12 91/12/19 SMI";
#endif
*/
/*
* Copyright (c) 1989 by Sun Microsystems, Inc.
*/
#include "reentrant.h"
#include "namespace.h"
#include <sys/cdefs.h>
#include <stdio.h>
#include <errno.h>
#include <netconfig.h>
#include <stdlib.h>
#include <string.h>
#include <rpc/rpc.h>
#include "un-namespace.h"
#include "rpc_com.h"
/*
* The five library routines in this file provide application access to the
* system network configuration database, /etc/netconfig. In addition to the
* netconfig database and the routines for accessing it, the environment
* variable NETPATH and its corresponding routines in getnetpath.c may also be
* used to specify the network transport to be used.
*/
/*
* netconfig errors
*/
#define NC_NONETCONFIG ENOENT
#define NC_NOMEM ENOMEM
#define NC_NOTINIT EINVAL /* setnetconfig was not called first */
#define NC_BADFILE EBADF /* format for netconfig file is bad */
/*
* semantics as strings (should be in netconfig.h)
*/
#define NC_TPI_CLTS_S "tpi_clts"
#define NC_TPI_COTS_S "tpi_cots"
#define NC_TPI_COTS_ORD_S "tpi_cots_ord"
#define NC_TPI_RAW_S "tpi_raw"
/*
* flags as characters (also should be in netconfig.h)
*/
#define NC_NOFLAG_C '-'
#define NC_VISIBLE_C 'v'
#define NC_BROADCAST_C 'b'
/*
* Character used to indicate there is no name-to-address lookup library
*/
#define NC_NOLOOKUP "-"
static const char * const _nc_errors[] = {
"Netconfig database not found",
"Not enough memory",
"Not initialized",
"Netconfig database has invalid format"
};
struct netconfig_info {
int eof; /* all entries has been read */
int ref; /* # of times setnetconfig() has been called */
struct netconfig_list *head; /* head of the list */
struct netconfig_list *tail; /* last of the list */
};
struct netconfig_list {
char *linep; /* hold line read from netconfig */
struct netconfig *ncp;
struct netconfig_list *next;
};
struct netconfig_vars {
int valid; /* token that indicates a valid netconfig_vars */
int flag; /* first time flag */
struct netconfig_list *nc_configs; /* pointer to the current netconfig entry */
};
#define NC_VALID 0xfeed
#define NC_STORAGE 0xf00d
#define NC_INVALID 0
static int *__nc_error __P((void));
static int parse_ncp __P((char *, struct netconfig *));
static struct netconfig *dup_ncp __P((struct netconfig *));
static FILE *nc_file; /* for netconfig db */
static struct netconfig_info ni = { 0, 0, NULL, NULL};
#define MAXNETCONFIGLINE 1000
static int *
__nc_error()
{
extern pthread_mutex_t nc_lock;
static thread_key_t nc_key = 0;
static thread_key_t rce_key = 0;
int *nc_addr = NULL;
static int nc_error = 0;
if ((nc_addr = (int *)thr_getspecific(nc_key)) != 0) {
mutex_lock(&nc_lock);
if (thr_keycreate(&rce_key, free) != 0) {
mutex_unlock(&nc_lock);
return nc_addr;
}
mutex_unlock(&nc_lock);
}
if (nc_addr == NULL) {
nc_addr = (int *)malloc(sizeof (int));
if (thr_setspecific(nc_key, (void *) nc_addr) != 0) {
if (nc_addr)
free(nc_addr);
return &nc_error;
}
*nc_addr = 0;
return nc_addr;
}
return nc_addr;
}
#define nc_error (*(__nc_error()))
/*
* A call to setnetconfig() establishes a /etc/netconfig "session". A session
* "handle" is returned on a successful call. At the start of a session (after
* a call to setnetconfig()) searches through the /etc/netconfig database will
* proceed from the start of the file. The session handle must be passed to
* getnetconfig() to parse the file. Each call to getnetconfig() using the
* current handle will process one subsequent entry in /etc/netconfig.
* setnetconfig() must be called before the first call to getnetconfig().
* (Handles are used to allow for nested calls to setnetpath()).
*
* A new session is established with each call to setnetconfig(), with a new
* handle being returned on each call. Previously established sessions remain
* active until endnetconfig() is called with that session's handle as an
* argument.
*
* setnetconfig() need *not* be called before a call to getnetconfigent().
* setnetconfig() returns a NULL pointer on failure (for example, if
* the netconfig database is not present).
*/
void *
setnetconfig()
{
struct netconfig_vars *nc_vars;
if ((nc_vars = (struct netconfig_vars *)malloc(sizeof
(struct netconfig_vars))) == NULL) {
return(NULL);
}
/*
* For multiple calls, i.e. nc_file is not NULL, we just return the
* handle without reopening the netconfig db.
*/
ni.ref++;
if ((nc_file != NULL) || (nc_file = fopen(NETCONFIG, "r")) != NULL) {
nc_vars->valid = NC_VALID;
nc_vars->flag = 0;
nc_vars->nc_configs = ni.head;
return ((void *)nc_vars);
}
ni.ref--;
nc_error = NC_NONETCONFIG;
free(nc_vars);
return (NULL);
}
/*
* When first called, getnetconfig() returns a pointer to the first entry in
* the netconfig database, formatted as a struct netconfig. On each subsequent
* call, getnetconfig() returns a pointer to the next entry in the database.
* getnetconfig() can thus be used to search the entire netconfig file.
* getnetconfig() returns NULL at end of file.
*/
struct netconfig *
getnetconfig(handlep)
void *handlep;
{
struct netconfig_vars *ncp = (struct netconfig_vars *)handlep;
char *stringp; /* tmp string pointer */
struct netconfig_list *list;
struct netconfig *np;
/*
* Verify that handle is valid
*/
if (ncp == NULL || nc_file == NULL) {
nc_error = NC_NOTINIT;
return (NULL);
}
switch (ncp->valid) {
case NC_VALID:
/*
* If entry has already been read into the list,
* we return the entry in the linked list.
* If this is the first time call, check if there are any entries in
* linked list. If no entries, we need to read the netconfig db.
* If we have been here and the next entry is there, we just return
* it.
*/
if (ncp->flag == 0) { /* first time */
ncp->flag = 1;
ncp->nc_configs = ni.head;
if (ncp->nc_configs != NULL) /* entry already exist */
return(ncp->nc_configs->ncp);
}
else if (ncp->nc_configs != NULL && ncp->nc_configs->next != NULL) {
ncp->nc_configs = ncp->nc_configs->next;
return(ncp->nc_configs->ncp);
}
/*
* If we cannot find the entry in the list and is end of file,
* we give up.
*/
if (ni.eof == 1) return(NULL);
break;
default:
nc_error = NC_NOTINIT;
return (NULL);
}
stringp = (char *) malloc(MAXNETCONFIGLINE);
if (stringp == NULL)
return (NULL);
#ifdef MEM_CHK
if (malloc_verify() == 0) {
fprintf(stderr, "memory heap corrupted in getnetconfig\n");
exit(1);
}
#endif
/*
* Read a line from netconfig file.
*/
do {
if (fgets(stringp, MAXNETCONFIGLINE, nc_file) == NULL) {
free(stringp);
ni.eof = 1;
return (NULL);
}
} while (*stringp == '#');
list = (struct netconfig_list *) malloc(sizeof (struct netconfig_list));
if (list == NULL) {
free(stringp);
return(NULL);
}
np = (struct netconfig *) malloc(sizeof (struct netconfig));
if (np == NULL) {
free(stringp);
free(list);
return(NULL);
}
list->ncp = np;
list->next = NULL;
list->ncp->nc_lookups = NULL;
list->linep = stringp;
if (parse_ncp(stringp, list->ncp) == -1) {
free(stringp);
free(np);
free(list);
return (NULL);
}
else {
/*
* If this is the first entry that's been read, it is the head of
* the list. If not, put the entry at the end of the list.
* Reposition the current pointer of the handle to the last entry
* in the list.
*/
if (ni.head == NULL) { /* first entry */
ni.head = ni.tail = list;
}
else {
ni.tail->next = list;
ni.tail = ni.tail->next;
}
ncp->nc_configs = ni.tail;
return(ni.tail->ncp);
}
}
/*
* endnetconfig() may be called to "unbind" or "close" the netconfig database
* when processing is complete, releasing resources for reuse. endnetconfig()
* may not be called before setnetconfig(). endnetconfig() returns 0 on
* success and -1 on failure (for example, if setnetconfig() was not called
* previously).
*/
int
endnetconfig(handlep)
void *handlep;
{
struct netconfig_vars *nc_handlep = (struct netconfig_vars *)handlep;
struct netconfig_list *q, *p;
/*
* Verify that handle is valid
*/
if (nc_handlep == NULL || (nc_handlep->valid != NC_VALID &&
nc_handlep->valid != NC_STORAGE)) {
nc_error = NC_NOTINIT;
return (-1);
}
/*
* Return 0 if anyone still needs it.
*/
nc_handlep->valid = NC_INVALID;
nc_handlep->flag = 0;
nc_handlep->nc_configs = NULL;
if (--ni.ref > 0) {
free(nc_handlep);
return(0);
}
/*
* Noone needs these entries anymore, then frees them.
* Make sure all info in netconfig_info structure has been reinitialized.
*/
q = p = ni.head;
ni.eof = ni.ref = 0;
ni.head = NULL;
ni.tail = NULL;
while (q) {
p = q->next;
if (q->ncp->nc_lookups != NULL) free(q->ncp->nc_lookups);
free(q->ncp);
free(q->linep);
free(q);
q = p;
}
free(nc_handlep);
fclose(nc_file);
nc_file = NULL;
return (0);
}
/*
* getnetconfigent(netid) returns a pointer to the struct netconfig structure
* corresponding to netid. It returns NULL if netid is invalid (that is, does
* not name an entry in the netconfig database). It returns NULL and sets
* errno in case of failure (for example, if the netconfig database cannot be
* opened).
*/
struct netconfig *
getnetconfigent(netid)
char *netid;
{
FILE *file; /* NETCONFIG db's file pointer */
char *linep; /* holds current netconfig line */
char *stringp; /* temporary string pointer */
struct netconfig *ncp = NULL; /* returned value */
struct netconfig_list *list; /* pointer to cache list */
if (netid == NULL || strlen(netid) == 0) {
return (NULL);
}
/*
* Look up table if the entries have already been read and parsed in
* getnetconfig(), then copy this entry into a buffer and return it.
* If we cannot find the entry in the current list and there are more
* entries in the netconfig db that has not been read, we then read the
* db and try find the match netid.
* If all the netconfig db has been read and placed into the list and
* there is no match for the netid, return NULL.
*/
if (ni.head != NULL) {
for (list = ni.head; list; list = list->next) {
if (strcmp(list->ncp->nc_netid, netid) == 0) {
return(dup_ncp(list->ncp));
}
}
if (ni.eof == 1) /* that's all the entries */
return(NULL);
}
if ((file = fopen(NETCONFIG, "r")) == NULL) {
return (NULL);
}
if ((linep = malloc(MAXNETCONFIGLINE)) == NULL) {
fclose(file);
return (NULL);
}
do {
int len;
char *tmpp; /* tmp string pointer */
do {
if ((stringp = fgets(linep, MAXNETCONFIGLINE, file)) == NULL) {
break;
}
} while (*stringp == '#');
if (stringp == NULL) { /* eof */
break;
}
if ((tmpp = strpbrk(stringp, "\t ")) == NULL) { /* can't parse file */
nc_error = NC_BADFILE;
break;
}
if (strlen(netid) == (len = tmpp - stringp) && /* a match */
strncmp(stringp, netid, (size_t)len) == 0) {
if ((ncp = (struct netconfig *)
malloc(sizeof (struct netconfig))) == NULL) {
break;
}
ncp->nc_lookups = NULL;
if (parse_ncp(linep, ncp) == -1) {
free(ncp);
ncp = NULL;
}
break;
}
} while (stringp != NULL);
if (ncp == NULL) {
free(linep);
}
fclose(file);
return(ncp);
}
/*
* freenetconfigent(netconfigp) frees the netconfig structure pointed to by
* netconfigp (previously returned by getnetconfigent()).
*/
void
freenetconfigent(netconfigp)
struct netconfig *netconfigp;
{
if (netconfigp != NULL) {
free(netconfigp->nc_netid); /* holds all netconfigp's strings */
if (netconfigp->nc_lookups != NULL)
free(netconfigp->nc_lookups);
free(netconfigp);
}
return;
}
/*
* Parse line and stuff it in a struct netconfig
* Typical line might look like:
* udp tpi_cots vb inet udp /dev/udp /usr/lib/ip.so,/usr/local/ip.so
*
* We return -1 if any of the tokens don't parse, or malloc fails.
*
* Note that we modify stringp (putting NULLs after tokens) and
* we set the ncp's string field pointers to point to these tokens within
* stringp.
*/
static int
parse_ncp(stringp, ncp)
char *stringp; /* string to parse */
struct netconfig *ncp; /* where to put results */
{
char *tokenp; /* for processing tokens */
char *lasts;
nc_error = NC_BADFILE; /* nearly anything that breaks is for this reason */
stringp[strlen(stringp)-1] = '\0'; /* get rid of newline */
/* netid */
if ((ncp->nc_netid = strtok_r(stringp, "\t ", &lasts)) == NULL) {
return (-1);
}
/* semantics */
if ((tokenp = strtok_r(NULL, "\t ", &lasts)) == NULL) {
return (-1);
}
if (strcmp(tokenp, NC_TPI_COTS_ORD_S) == 0)
ncp->nc_semantics = NC_TPI_COTS_ORD;
else if (strcmp(tokenp, NC_TPI_COTS_S) == 0)
ncp->nc_semantics = NC_TPI_COTS;
else if (strcmp(tokenp, NC_TPI_CLTS_S) == 0)
ncp->nc_semantics = NC_TPI_CLTS;
else if (strcmp(tokenp, NC_TPI_RAW_S) == 0)
ncp->nc_semantics = NC_TPI_RAW;
else
return (-1);
/* flags */
if ((tokenp = strtok_r(NULL, "\t ", &lasts)) == NULL) {
return (-1);
}
for (ncp->nc_flag = NC_NOFLAG; *tokenp != '\0';
tokenp++) {
switch (*tokenp) {
case NC_NOFLAG_C:
break;
case NC_VISIBLE_C:
ncp->nc_flag |= NC_VISIBLE;
break;
case NC_BROADCAST_C:
ncp->nc_flag |= NC_BROADCAST;
break;
default:
return (-1);
}
}
/* protocol family */
if ((ncp->nc_protofmly = strtok_r(NULL, "\t ", &lasts)) == NULL) {
return (-1);
}
/* protocol name */
if ((ncp->nc_proto = strtok_r(NULL, "\t ", &lasts)) == NULL) {
return (-1);
}
/* network device */
if ((ncp->nc_device = strtok_r(NULL, "\t ", &lasts)) == NULL) {
return (-1);
}
if ((tokenp = strtok_r(NULL, "\t ", &lasts)) == NULL) {
return (-1);
}
if (strcmp(tokenp, NC_NOLOOKUP) == 0) {
ncp->nc_nlookups = 0;
ncp->nc_lookups = NULL;
} else {
char *cp; /* tmp string */
if (ncp->nc_lookups != NULL) /* from last visit */
free(ncp->nc_lookups);
/* preallocate one string pointer */
ncp->nc_lookups = (char **)malloc(sizeof (char *));
ncp->nc_nlookups = 0;
while ((cp = tokenp) != NULL) {
tokenp = _get_next_token(cp, ',');
ncp->nc_lookups[(size_t)ncp->nc_nlookups++] = cp;
ncp->nc_lookups = (char **)realloc(ncp->nc_lookups,
(size_t)(ncp->nc_nlookups+1) *sizeof(char *)); /* for next loop */
}
}
return (0);
}
/*
* Returns a string describing the reason for failure.
*/
char *
nc_sperror()
{
const char *message;
switch(nc_error) {
case NC_NONETCONFIG:
message = _nc_errors[0];
break;
case NC_NOMEM:
message = _nc_errors[1];
break;
case NC_NOTINIT:
message = _nc_errors[2];
break;
case NC_BADFILE:
message = _nc_errors[3];
break;
default:
message = "Unknown network selection error";
}
/* LINTED const castaway */
return ((char *)message);
}
/*
* Prints a message onto standard error describing the reason for failure.
*/
void
nc_perror(s)
const char *s;
{
fprintf(stderr, "%s: %s", s, nc_sperror());
}
/*
* Duplicates the matched netconfig buffer.
*/
static struct netconfig *
dup_ncp(ncp)
struct netconfig *ncp;
{
struct netconfig *p;
char *tmp;
int i;
if ((tmp=malloc(MAXNETCONFIGLINE)) == NULL)
return(NULL);
if ((p=(struct netconfig *)malloc(sizeof(struct netconfig))) == NULL) {
free(tmp);
return(NULL);
}
/*
* First we dup all the data from matched netconfig buffer. Then we
* adjust some of the member pointer to a pre-allocated buffer where
* contains part of the data.
* To follow the convention used in parse_ncp(), we store all the
* neccessary information in the pre-allocated buffer and let each
* of the netconfig char pointer member point to the right address
* in the buffer.
*/
*p = *ncp;
p->nc_netid = (char *)strcpy(tmp,ncp->nc_netid);
tmp = strchr(tmp, NULL) + 1;
p->nc_protofmly = (char *)strcpy(tmp,ncp->nc_protofmly);
tmp = strchr(tmp, NULL) + 1;
p->nc_proto = (char *)strcpy(tmp,ncp->nc_proto);
tmp = strchr(tmp, NULL) + 1;
p->nc_device = (char *)strcpy(tmp,ncp->nc_device);
p->nc_lookups = (char **)malloc((size_t)(p->nc_nlookups+1) * sizeof(char *));
if (p->nc_lookups == NULL) {
free(p->nc_netid);
return(NULL);
}
for (i=0; i < p->nc_nlookups; i++) {
tmp = strchr(tmp, NULL) + 1;
p->nc_lookups[i] = (char *)strcpy(tmp,ncp->nc_lookups[i]);
}
return(p);
}

154
lib/libc/rpc/getnetpath.3 Normal file
View File

@ -0,0 +1,154 @@
.\" @(#)getnetpath.3n 1.26 93/05/07 SMI; from SVr4
.\" $NetBSD: getnetpath.3,v 1.1 2000/06/02 23:11:11 fvdl Exp $
.\" $FreeBSD$
.\" Copyright 1989 AT&T
.Dd April 22, 2000
.Dt GETNETPATH 3
.Os
.Sh NAME
.Nm getnetpath ,
.Nm setnetpath ,
.Nm endnetpath
.Nd get
.Pa /etc/netconfig
entry corresponding to
.Ev NETPATH
component
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.Fd #include <netconfig.h>
.Ft "struct netconfig *"
.Fn getnetpath "void *handlep"
.Ft "void *"
.Fn setnetpath "void"
.Ft int
.Fn endnetpath "void *handlep"
.Sh DESCRIPTION
The routines described in this page provide the application access to the system
network configuration database,
.Pa /etc/netconfig ,
as it is
.Dq filtered
by the
.Ev NETPATH
environment variable (see
.Xr environ 5 ) .
See
.Xr getnetconfig 3
for other routines that also access the
network configuration database directly.
The
.Ev NETPATH
variable is a list of colon-separated network identifiers.
.Pp
.Fn getnetpath
returns a pointer to the
netconfig database entry corresponding to the first valid
.Ev NETPATH
component.
The netconfig entry is formatted as a
.Ft "struct netconfig" .
On each subsequent call,
.Fn getnetpath
returns a pointer to the netconfig entry that corresponds to the next
valid
.Ev NETPATH
component.
.Fn getnetpath
can thus be used to search the netconfig database for all networks
included in the
.Ev NETPATH
variable.
When
.Ev NETPATH
has been exhausted,
.Fn getnetpath
returns
.Dv NULL .
.Pp
A call to
.Fn setnetpath
.Dq binds
to or
.Dq rewinds
.Ev NETPATH .
.Fn setnetpath
must be called before the first call to
.Fn getnetpath
and may be called at any other time.
It returns a handle that is used by
.Fn getnetpath .
.Pp
.Fn getnetpath
silently ignores invalid
.Ev NETPATH
components.
A
.Ev NETPATH
component is invalid if there is no corresponding
entry in the netconfig database.
.Pp
If the
.Ev NETPATH
variable is unset,
.Fn getnetpath
behaves as if
.Ev NETPATH
were set to the sequence of
.Dq default
or
.Dq visible
networks in the netconfig database, in the
order in which they are listed.
.\"This proviso holds also for this
.\"whole manpage.
.Pp
.Fn endnetpath
may be called to
.Dq unbind
from
.Ev NETPATH
when processing is complete, releasing resources for reuse.
Programmers should be aware, however, that
.Fn endnetpath
frees all memory allocated by
.Fn getnetpath
for the struct netconfig data structure.
.Sh RETURN VALUES
.Fn setnetpath
returns a handle that is used by
.Fn getnetpath .
In case of an error,
.Fn setnetpath
returns
.Dv NULL .
.Pp
.Fn endnetpath
returns 0 on success and \-1 on failure
(for example, if
.Fn setnetpath
was not called previously).
.Fn nc_perror
or
.Fn nc_sperror
can be used to print out the reason for failure.
See
.Xr getnetconfig 3 .
.Pp
When first called,
.Fn getnetpath
returns a pointer to the netconfig database entry corresponding to the first
valid
.Ev NETPATH
component.
When
.Ev NETPATH
has been exhausted,
.Fn getnetpath
returns
.Dv NULL .
.Sh SEE ALSO
.Xr getnetconfig 3 ,
.Xr environ 5 ,
.Xr netconfig 5

273
lib/libc/rpc/getnetpath.c Normal file
View File

@ -0,0 +1,273 @@
/* $NetBSD: getnetpath.c,v 1.3 2000/07/06 03:10:34 christos Exp $ */
/* $FreeBSD$ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user or with the express written consent of
* Sun Microsystems, Inc.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
#ifndef lint
static char sccsid[] = "@(#)getnetpath.c 1.11 91/12/19 SMI";
#endif
*/
/*
* Copyright (c) 1989 by Sun Microsystems, Inc.
*/
#include "namespace.h"
#include <sys/cdefs.h>
#include <stdio.h>
#include <errno.h>
#include <netconfig.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include "un-namespace.h"
/*
* internal structure to keep track of a netpath "session"
*/
struct netpath_chain {
struct netconfig *ncp; /* an nconf entry */
struct netpath_chain *nchain_next; /* next nconf entry allocated */
};
struct netpath_vars {
int valid; /* token that indicates a valid netpath_vars */
void *nc_handlep; /* handle for current netconfig "session" */
char *netpath; /* pointer to current view-point in NETPATH */
char *netpath_start; /* pointer to start of our copy of NETPATH */
struct netpath_chain *ncp_list; /* list of nconfs allocated this session*/
};
#define NP_VALID 0xf00d
#define NP_INVALID 0
char *_get_next_token __P((char *, int));
/*
* A call to setnetpath() establishes a NETPATH "session". setnetpath()
* must be called before the first call to getnetpath(). A "handle" is
* returned to distinguish the session; this handle should be passed
* subsequently to getnetpath(). (Handles are used to allow for nested calls
* to setnetpath()).
* If setnetpath() is unable to establish a session (due to lack of memory
* resources, or the absence of the /etc/netconfig file), a NULL pointer is
* returned.
*/
void *
setnetpath()
{
struct netpath_vars *np_sessionp; /* this session's variables */
char *npp; /* NETPATH env variable */
#ifdef MEM_CHK
malloc_debug(1);
#endif
if ((np_sessionp =
(struct netpath_vars *)malloc(sizeof (struct netpath_vars))) == NULL) {
return (NULL);
}
if ((np_sessionp->nc_handlep = setnetconfig()) == NULL) {
syslog (LOG_ERR, "rpc: failed to open " NETCONFIG);
return (NULL);
}
np_sessionp->valid = NP_VALID;
np_sessionp->ncp_list = NULL;
if ((npp = getenv(NETPATH)) == NULL) {
np_sessionp->netpath = NULL;
} else {
(void) endnetconfig(np_sessionp->nc_handlep);/* won't need nc session*/
np_sessionp->nc_handlep = NULL;
if ((np_sessionp->netpath = malloc(strlen(npp)+1)) == NULL) {
free(np_sessionp);
return (NULL);
} else {
(void) strcpy(np_sessionp->netpath, npp);
}
}
np_sessionp->netpath_start = np_sessionp->netpath;
return ((void *)np_sessionp);
}
/*
* When first called, getnetpath() returns a pointer to the netconfig
* database entry corresponding to the first valid NETPATH component. The
* netconfig entry is formatted as a struct netconfig.
* On each subsequent call, getnetpath returns a pointer to the netconfig
* entry that corresponds to the next valid NETPATH component. getnetpath
* can thus be used to search the netconfig database for all networks
* included in the NETPATH variable.
* When NETPATH has been exhausted, getnetpath() returns NULL. It returns
* NULL and sets errno in case of an error (e.g., setnetpath was not called
* previously).
* getnetpath() silently ignores invalid NETPATH components. A NETPATH
* compnent is invalid if there is no corresponding entry in the netconfig
* database.
* If the NETPATH variable is unset, getnetpath() behaves as if NETPATH
* were set to the sequence of default or visible networks in the netconfig
* database, in the order in which they are listed.
*/
struct netconfig *
getnetpath(handlep)
void *handlep;
{
struct netpath_vars *np_sessionp = (struct netpath_vars *)handlep;
struct netconfig *ncp = NULL; /* temp. holds a netconfig session */
struct netpath_chain *chainp; /* holds chain of ncp's we alloc */
char *npp; /* holds current NETPATH */
if (np_sessionp == NULL || np_sessionp->valid != NP_VALID) {
errno = EINVAL;
return (NULL);
}
if (np_sessionp->netpath_start == NULL) { /* NETPATH was not set */
do { /* select next visible network */
if (np_sessionp->nc_handlep == NULL) {
np_sessionp->nc_handlep = setnetconfig();
if (np_sessionp->nc_handlep == NULL)
syslog (LOG_ERR, "rpc: failed to open " NETCONFIG);
}
if ((ncp = getnetconfig(np_sessionp->nc_handlep)) == NULL) {
return(NULL);
}
} while ((ncp->nc_flag & NC_VISIBLE) == 0);
return (ncp);
}
/*
* Find first valid network ID in netpath.
*/
while ((npp = np_sessionp->netpath) != NULL && strlen(npp) != 0) {
np_sessionp->netpath = _get_next_token(npp, ':');
/*
* npp is a network identifier.
*/
if ((ncp = getnetconfigent(npp)) != NULL) {
chainp = (struct netpath_chain *) /* cobble alloc chain entry */
malloc(sizeof (struct netpath_chain));
chainp->ncp = ncp;
chainp->nchain_next = NULL;
if (np_sessionp->ncp_list == NULL) {
np_sessionp->ncp_list = chainp;
} else {
np_sessionp->ncp_list->nchain_next = chainp;
}
return (ncp);
}
/* couldn't find this token in the database; go to next one. */
}
return (NULL);
}
/*
* endnetpath() may be called to unbind NETPATH when processing is complete,
* releasing resources for reuse. It returns 0 on success and -1 on failure
* (e.g. if setnetpath() was not called previously.
*/
int
endnetpath(handlep)
void *handlep;
{
struct netpath_vars *np_sessionp = (struct netpath_vars *)handlep;
struct netpath_chain *chainp, *lastp;
if (np_sessionp == NULL || np_sessionp->valid != NP_VALID) {
errno = EINVAL;
return (-1);
}
if (np_sessionp->nc_handlep != NULL)
endnetconfig(np_sessionp->nc_handlep);
if (np_sessionp->netpath_start != NULL)
free(np_sessionp->netpath_start);
for (chainp = np_sessionp->ncp_list; chainp != NULL;
lastp=chainp, chainp=chainp->nchain_next, free(lastp)) {
freenetconfigent(chainp->ncp);
}
free(np_sessionp);
#ifdef MEM_CHK
if (malloc_verify() == 0) {
fprintf(stderr, "memory heap corrupted in endnetpath\n");
exit(1);
}
#endif
return (0);
}
/*
* Returns pointer to the rest-of-the-string after the current token.
* The token itself starts at arg, and we null terminate it. We return NULL
* if either the arg is empty, or if this is the last token.
*/
char *
_get_next_token(npp, token)
char *npp; /* string */
int token; /* char to parse string for */
{
char *cp; /* char pointer */
char *np; /* netpath pointer */
char *ep; /* escape pointer */
if ((cp = strchr(npp, token)) == NULL) {
return (NULL);
}
/*
* did find a token, but it might be escaped.
*/
if (cp[-1] == '\\') {
/* if slash was also escaped, carry on, otherwise find next token */
if (cp[-2] != '\\') {
/* shift r-o-s onto the escaped token */
strcpy(&cp[-1], cp); /* XXX: overlapping string copy */
/*
* Do a recursive call.
* We don't know how many escaped tokens there might be.
*/
return (_get_next_token(cp, token));
}
}
*cp++ = '\0'; /* null-terminate token */
/* get rid of any backslash escapes */
ep = npp;
while ((np = strchr(ep, '\\')) != 0) {
if (np[1] == '\\')
np++;
strcpy(np, (ep = &np[1])); /* XXX: overlapping string copy */
}
return (cp); /* return ptr to r-o-s */
}

View File

@ -41,6 +41,7 @@ static char sccsid[] = "@(#)publickey.c 1.10 91/03/11 Copyr 1986 Sun Micro";
/*
* Public key lookup routines
*/
#include "namespace.h"
#include <stdio.h>
#include <pwd.h>
#include <rpc/rpc.h>
@ -49,6 +50,7 @@ static char sccsid[] = "@(#)publickey.c 1.10 91/03/11 Copyr 1986 Sun Micro";
#include <rpcsvc/ypclnt.h>
#include <string.h>
#include <stdlib.h>
#include "un-namespace.h"
#define PKFILE "/etc/publickey"

View File

@ -1,4 +1,5 @@
.\" @(#)getrpcent.3n 2.2 88/08/02 4.0 RPCSRC; from 1.11 88/03/14 SMI
.\" $NetBSD: getrpcent.3,v 1.6 1998/02/05 18:49:06 perry Exp $
.\" $FreeBSD$
.\"
.Dd December 14, 1987
@ -11,6 +12,8 @@
.Nm endrpcent ,
.Nm setrpcent
.Nd get RPC entry
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.Fd #include <rpc/rpc.h>
.Ft struct rpcent *
@ -24,19 +27,17 @@
.Ft void
.Fn endrpcent void
.Sh DESCRIPTION
The
.Fn getrpcent ,
.Fn getrpcbyname ,
and
.Fn getrpcbynumber
functions each return a pointer to an object with the
each return a pointer to an object with the
following structure
containing the broken-out
fields of a line in the rpc program number data base,
.Pa /etc/rpc .
.Pa /etc/rpc :
.Bd -literal
struct rpcent {
struct rpcent {
char *r_name; /* name of server for this rpc program */
char **r_aliases; /* alias list */
long r_number; /* rpc program number */
@ -44,29 +45,28 @@ struct rpcent {
.Ed
.Pp
The members of this structure are:
.Bl -tag -width r_aliasesxxx
.It Fa r_name
.Bl -tag -width r_aliases -offset indent
.It Va r_name
The name of the server for this rpc program.
.It Fa r_aliases
.It Va r_aliases
A zero terminated list of alternate names for the rpc program.
.It Fa r_number
.It Va r_number
The rpc program number for this service.
.El
.Pp
The
.Fn getrpcent
function reads the next line of the file, opening the file if necessary.
The
reads the next line of the file, opening the file if necessary.
.Pp
.Fn setrpcent
function opens and rewinds the file. If the
opens and rewinds the file. If the
.Fa stayopen
flag is non-zero,
the net data base will not be closed after each call to
.Fn getrpcent
(either directly, or indirectly through one of
the other
.Fn getrpcent
function family.
.Dq getrpc
calls).
.Pp
.Fn endrpcent
closes the file.
@ -81,7 +81,7 @@ program number is found, or until end-of-file is encountered.
.Bl -tag -width /etc/rpc -compact
.It Pa /etc/rpc
.El
.Sh "SEE ALSO"
.Sh SEE ALSO
.Xr rpc 5 ,
.Xr rpcinfo 8 ,
.Xr ypserv 8

View File

@ -1,3 +1,5 @@
/* $NetBSD: getrpcent.c,v 1.17 2000/01/22 22:19:17 mycroft Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -28,8 +30,9 @@
* Mountain View, California 94043
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro";*/
static char *sccsid = "@(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro";
static char *rcsid = "$FreeBSD$";
#endif
@ -37,20 +40,29 @@ static char *rcsid = "$FreeBSD$";
* Copyright (c) 1984 by Sun Microsystems, Inc.
*/
#include "namespace.h"
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <rpc/rpc.h>
#ifdef YP
#include <rpcsvc/yp_prot.h>
#include <rpcsvc/ypclnt.h>
#endif
#include "un-namespace.h"
/*
* Internet version.
*/
struct rpcdata {
static struct rpcdata {
FILE *rpcf;
int stayopen;
#define MAXALIASES 35
@ -64,21 +76,21 @@ struct rpcdata {
#endif
} *rpcdata;
static struct rpcent *interpret __P((char *val, size_t len));
#ifdef YP
static int __yp_nomap = 0;
extern int _yp_check(char **);
#endif /* YP */
static struct rpcent *interpret();
struct hostent *gethostent();
char *inet_ntoa();
#define RPCDB "/etc/rpc"
static char RPCDB[] = "/etc/rpc";
static struct rpcdata *_rpcdata __P((void));
static struct rpcdata *
_rpcdata()
{
register struct rpcdata *d = rpcdata;
struct rpcdata *d = rpcdata;
if (d == 0) {
d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata));
@ -89,14 +101,14 @@ _rpcdata()
struct rpcent *
getrpcbynumber(number)
register int number;
int number;
{
register struct rpcdata *d = _rpcdata();
register struct rpcent *p;
#ifdef YP
int reason;
char adrstr[16];
#endif
struct rpcent *p;
struct rpcdata *d = _rpcdata();
if (d == 0)
return (0);
@ -123,8 +135,9 @@ getrpcbynumber(number)
}
no_yp:
#endif /* YP */
setrpcent(0);
while ((p = getrpcent())) {
while ((p = getrpcent()) != NULL) {
if (p->r_number == number)
break;
}
@ -139,8 +152,10 @@ getrpcbyname(name)
struct rpcent *rpc = NULL;
char **rp;
assert(name != NULL);
setrpcent(0);
while ((rpc = getrpcent())) {
while ((rpc = getrpcent()) != NULL) {
if (strcmp(rpc->r_name, name) == 0)
goto done;
for (rp = rpc->r_aliases; *rp != NULL; rp++) {
@ -157,7 +172,7 @@ void
setrpcent(f)
int f;
{
register struct rpcdata *d = _rpcdata();
struct rpcdata *d = _rpcdata();
if (d == 0)
return;
@ -181,7 +196,7 @@ setrpcent(f)
void
endrpcent()
{
register struct rpcdata *d = _rpcdata();
struct rpcdata *d = _rpcdata();
if (d == 0)
return;
@ -204,7 +219,7 @@ endrpcent()
struct rpcent *
getrpcent()
{
register struct rpcdata *d = _rpcdata();
struct rpcdata *d = _rpcdata();
#ifdef YP
struct rpcent *hp;
int reason;
@ -255,11 +270,13 @@ getrpcent()
static struct rpcent *
interpret(val, len)
char *val;
int len;
size_t len;
{
register struct rpcdata *d = _rpcdata();
struct rpcdata *d = _rpcdata();
char *p;
register char *cp, **q;
char *cp, **q;
assert(val != NULL);
if (d == 0)
return (0);

View File

@ -7,6 +7,8 @@
.Sh NAME
.Nm getrpcport
.Nd get RPC port number
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.Ft int
.Fn getrpcport "char *host" "int prognum" "int versnum" "int proto"

View File

@ -1,3 +1,5 @@
/* $NetBSD: getrpcport.c,v 1.16 2000/01/22 22:19:18 mycroft Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -27,9 +29,10 @@
* Mountain View, California 94043
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)getrpcport.c 1.3 87/08/11 SMI";*/
/*static char *sccsid = "from: @(#)getrpcport.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *sccsid = "@(#)getrpcport.c 1.3 87/08/11 SMI";
static char *sccsid = "@(#)getrpcport.c 2.1 88/07/29 4.0 RPCSRC";
static char *rcsid = "$FreeBSD$";
#endif
@ -37,12 +40,18 @@ static char *rcsid = "$FreeBSD$";
* Copyright (c) 1985 by Sun Microsystems, Inc.
*/
#include "namespace.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <assert.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <rpc/rpc.h>
#include <rpc/pmap_clnt.h>
#include <netdb.h>
#include <sys/socket.h>
#include "un-namespace.h"
int
getrpcport(host, prognum, versnum, proto)
@ -52,12 +61,18 @@ getrpcport(host, prognum, versnum, proto)
struct sockaddr_in addr;
struct hostent *hp;
assert(host != NULL);
if ((hp = gethostbyname(host)) == NULL)
return (0);
memset(&addr, 0, sizeof(addr));
addr.sin_len = sizeof(struct sockaddr_in);
addr.sin_family = AF_INET;
addr.sin_port = 0;
memcpy((char *)&addr.sin_addr, hp->h_addr, hp->h_length);
return (pmap_getport(&addr, prognum, versnum, proto));
if (hp->h_length > addr.sin_len)
hp->h_length = addr.sin_len;
memcpy(&addr.sin_addr.s_addr, hp->h_addr, (size_t)hp->h_length);
/* Inconsistent interfaces need casts! :-( */
return (pmap_getport(&addr, (u_long)prognum, (u_long)versnum,
(u_int)proto));
}

View File

@ -43,6 +43,7 @@
* gendeskey(deskey) - generate a secure des key
*/
#include "reentrant.h"
#include "namespace.h"
#include <stdio.h>
#include <stdlib.h>
@ -53,6 +54,7 @@
#include <rpc/auth_unix.h>
#include <rpc/key_prot.h>
#include <string.h>
#include <netconfig.h>
#include <sys/utsname.h>
#include <stdlib.h>
#include <signal.h>
@ -232,7 +234,7 @@ key_gendes(key)
int
key_setnet(arg)
struct netstarg *arg;
struct key_netstarg *arg;
{
keystatus status;
@ -276,7 +278,6 @@ struct key_call_private {
};
static struct key_call_private *key_call_private_main = NULL;
#ifdef foo
static void
key_call_destroy(void *vp)
{
@ -288,7 +289,6 @@ key_call_destroy(void *vp)
free(kcp);
}
}
#endif
/*
* Keep the handle cached. This call may be made quite often.
@ -297,21 +297,40 @@ static CLIENT *
getkeyserv_handle(vers)
int vers;
{
void *localhandle;
struct netconfig *nconf;
struct netconfig *tpconf;
struct key_call_private *kcp = key_call_private_main;
struct timeval wait_time;
struct utsname u;
int main_thread;
int fd;
struct sockaddr_un name;
int namelen = sizeof(struct sockaddr_un);
static thread_key_t key_call_key;
extern mutex_t tsd_lock;
#define TOTAL_TIMEOUT 30 /* total timeout talking to keyserver */
#define TOTAL_TRIES 5 /* Number of tries */
if ((main_thread = thr_main())) {
kcp = key_call_private_main;
} else {
if (key_call_key == 0) {
mutex_lock(&tsd_lock);
if (key_call_key == 0)
thr_keycreate(&key_call_key, key_call_destroy);
mutex_unlock(&tsd_lock);
}
kcp = (struct key_call_private *)thr_getspecific(key_call_key);
}
if (kcp == (struct key_call_private *)NULL) {
kcp = (struct key_call_private *)malloc(sizeof (*kcp));
if (kcp == (struct key_call_private *)NULL) {
return ((CLIENT *) NULL);
}
key_call_private_main = kcp;
if (main_thread)
key_call_private_main = kcp;
else
thr_setspecific(key_call_key, (void *) kcp);
kcp->client = NULL;
}
@ -321,16 +340,6 @@ int vers;
kcp->client = NULL;
}
if (kcp->client != NULL) {
/* if other side closed socket, build handle again */
clnt_control(kcp->client, CLGET_FD, (char *)&fd);
if (_getpeername(fd,(struct sockaddr *)&name,&namelen) == -1) {
auth_destroy(kcp->client->cl_auth);
clnt_destroy(kcp->client);
kcp->client = NULL;
}
}
if (kcp->client != NULL) {
/* if uid has changed, build client handle again */
if (kcp->uid != geteuid()) {
@ -348,15 +357,51 @@ int vers;
clnt_control(kcp->client, CLSET_VERS, (void *)&vers);
return (kcp->client);
}
if (!(localhandle = setnetconfig())) {
return ((CLIENT *) NULL);
}
tpconf = NULL;
#if defined(i386)
#if defined(__FreeBSD__)
if (uname(&u) == -1)
#else
if (_nuname(&u) == -1)
#endif
#elif defined(sparc)
if (_uname(&u) == -1)
#else
#error Unknown architecture!
#endif
{
endnetconfig(localhandle);
return ((CLIENT *) NULL);
}
if ((kcp->client == (CLIENT *) NULL))
/* Use the AF_UNIX transport */
kcp->client = clnt_create("/var/run/keyservsock", KEY_PROG,
vers, "unix");
while (nconf = getnetconfig(localhandle)) {
if (strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) {
/*
* We use COTS_ORD here so that the caller can
* find out immediately if the server is dead.
*/
if (nconf->nc_semantics == NC_TPI_COTS_ORD) {
kcp->client = clnt_tp_create(u.nodename,
KEY_PROG, vers, nconf);
if (kcp->client)
break;
} else {
tpconf = nconf;
}
}
}
if ((kcp->client == (CLIENT *) NULL) && (tpconf))
/* Now, try the CLTS or COTS loopback transport */
kcp->client = clnt_tp_create(u.nodename,
KEY_PROG, vers, tpconf);
endnetconfig(localhandle);
if (kcp->client == (CLIENT *) NULL) {
return ((CLIENT *) NULL);
}
}
kcp->uid = geteuid();
kcp->pid = getpid();
kcp->client->cl_auth = authsys_create("", kcp->uid, 0, 0, NULL);

View File

@ -3,7 +3,9 @@
* It was generated using rpcgen.
*/
#include "namespace.h"
#include <rpc/key_prot.h>
#include "un-namespace.h"
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -32,8 +34,8 @@
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#pragma ident "@(#)key_prot.x 1.7 94/04/29 SMI"
/* From: #pragma ident "@(#)key_prot.x 1.7 94/04/29 SMI" */
/* $FreeBSD$ */
/* Copyright (c) 1990, 1991 Sun Microsystems, Inc. */
/*

125
lib/libc/rpc/mt_misc.c Normal file
View File

@ -0,0 +1,125 @@
/* $NetBSD: mt_misc.c,v 1.1 2000/06/02 23:11:11 fvdl Exp $ */
/* $FreeBSD$ */
/* #pragma ident "@(#)mt_misc.c 1.24 93/04/29 SMI" */
#include "reentrant.h"
#include "namespace.h"
#include <rpc/rpc.h>
#include <sys/time.h>
#include <stdlib.h>
#include "un-namespace.h"
/* protects the services list (svc.c) */
pthread_rwlock_t svc_lock = PTHREAD_RWLOCK_INITIALIZER;
/* protects svc_fdset and the xports[] array */
pthread_rwlock_t svc_fd_lock = PTHREAD_RWLOCK_INITIALIZER;
/* protects the RPCBIND address cache */
pthread_rwlock_t rpcbaddr_cache_lock = PTHREAD_RWLOCK_INITIALIZER;
/* protects authdes cache (svcauth_des.c) */
pthread_mutex_t authdes_lock = PTHREAD_MUTEX_INITIALIZER;
/* serializes authdes ops initializations */
pthread_mutex_t authdes_ops_lock = PTHREAD_MUTEX_INITIALIZER;
/* protects des stats list */
pthread_mutex_t svcauthdesstats_lock = PTHREAD_MUTEX_INITIALIZER;
#ifdef KERBEROS
/* auth_kerb.c serialization */
pthread_mutex_t authkerb_lock = PTHREAD_MUTEX_INITIALIZER;
/* protects kerb stats list */
pthread_mutex_t svcauthkerbstats_lock = PTHREAD_MUTEX_INITIALIZER;
#endif /* KERBEROS */
/* auth_none.c serialization */
pthread_mutex_t authnone_lock = PTHREAD_MUTEX_INITIALIZER;
/* protects the Auths list (svc_auth.c) */
pthread_mutex_t authsvc_lock = PTHREAD_MUTEX_INITIALIZER;
/* protects client-side fd lock array */
pthread_mutex_t clnt_fd_lock = PTHREAD_MUTEX_INITIALIZER;
/* clnt_raw.c serialization */
pthread_mutex_t clntraw_lock = PTHREAD_MUTEX_INITIALIZER;
/* domainname and domain_fd (getdname.c) and default_domain (rpcdname.c) */
pthread_mutex_t dname_lock = PTHREAD_MUTEX_INITIALIZER;
/* dupreq variables (svc_dg.c) */
pthread_mutex_t dupreq_lock = PTHREAD_MUTEX_INITIALIZER;
/* protects first_time and hostname (key_call.c) */
pthread_mutex_t keyserv_lock = PTHREAD_MUTEX_INITIALIZER;
/* serializes rpc_trace() (rpc_trace.c) */
pthread_mutex_t libnsl_trace_lock = PTHREAD_MUTEX_INITIALIZER;
/* loopnconf (rpcb_clnt.c) */
pthread_mutex_t loopnconf_lock = PTHREAD_MUTEX_INITIALIZER;
/* serializes ops initializations */
pthread_mutex_t ops_lock = PTHREAD_MUTEX_INITIALIZER;
/* protects ``port'' static in bindresvport() */
pthread_mutex_t portnum_lock = PTHREAD_MUTEX_INITIALIZER;
/* protects proglst list (svc_simple.c) */
pthread_mutex_t proglst_lock = PTHREAD_MUTEX_INITIALIZER;
/* serializes clnt_com_create() (rpc_soc.c) */
pthread_mutex_t rpcsoc_lock = PTHREAD_MUTEX_INITIALIZER;
/* svc_raw.c serialization */
pthread_mutex_t svcraw_lock = PTHREAD_MUTEX_INITIALIZER;
/* protects TSD key creation */
pthread_mutex_t tsd_lock = PTHREAD_MUTEX_INITIALIZER;
/* protects netconfig list */
pthread_mutex_t nc_lock = PTHREAD_MUTEX_INITIALIZER;
/* xprtlist (svc_generic.c) */
pthread_mutex_t xprtlist_lock = PTHREAD_MUTEX_INITIALIZER;
/* serializes calls to public key routines */
pthread_mutex_t serialize_pkey = PTHREAD_MUTEX_INITIALIZER;
#undef rpc_createerr
struct rpc_createerr rpc_createerr;
struct rpc_createerr *
__rpc_createerr()
{
static thread_key_t rce_key = 0;
struct rpc_createerr *rce_addr = 0;
if (thr_main())
return (&rpc_createerr);
if ((rce_addr =
(struct rpc_createerr *)thr_getspecific(rce_key)) != 0) {
mutex_lock(&tsd_lock);
if (thr_keycreate(&rce_key, free) != 0) {
mutex_unlock(&tsd_lock);
return (&rpc_createerr);
}
mutex_unlock(&tsd_lock);
}
if (!rce_addr) {
rce_addr = (struct rpc_createerr *)
malloc(sizeof (struct rpc_createerr));
if (thr_setspecific(rce_key, (void *) rce_addr) != 0) {
if (rce_addr)
free(rce_addr);
return (&rpc_createerr);
}
memset(rce_addr, 0, sizeof (struct rpc_createerr));
return (rce_addr);
}
return (rce_addr);
}

126
lib/libc/rpc/netconfig.5 Normal file
View File

@ -0,0 +1,126 @@
.\" $NetBSD: netconfig.5,v 1.2 2000/11/08 13:18:28 lukem Exp $
.\" $NetBSD: netconfig.5,v 1.2 2000/11/08 13:18:28 lukem Exp $
.\" $FreeBSD$
.Dd November 17, 2000
.Dt NETCONFIG 5
.Os
.Sh NAME
.Nm netconfig
.Nd network configuration data base
.Sh SYNOPSIS
.Pa /etc/netconfig
.Sh DESCRIPTION
The
.Nm
file defines a list of
.Dq transport names ,
describing their semantics and protocol.
In
.Fx ,
this file is only used by the RPC library code.
.Pp
Entries have the following format:
.Pp
.Ar network_id semantics flags family protoname device libraries
.Pp
Entries consist of the following fields:
.Bl -tag -width network_id
.It Ar network_id
The name of the transport described.
.It Ar semantics
Describes the semantics of the transport.
This can be one of:
.Bl -tag -width tpi_cots_ord -offset indent
.It Sy tpi_clts
Connectionless transport.
.It Sy tpi_cots
Connection-oriented transport
.It Sy tpi_cots_ord
Connection-oriented, ordered transport.
.It Sy tpi_raw
A raw connection.
.El
.It Ar flags
This field is either blank (specified by
.Dq Li - ) ,
or contains a
.Dq Li v ,
meaning visible to the
.Xr getnetconfig 3
function.
.It Ar family
The protocol family of the transport.
This is currently one of:
.Bl -tag -width loopback -offset indent
.It Sy inet6
The IPv6
.Pq Dv PF_INET6
family of protocols.
.It Sy inet
The IPv4
.Pq Dv PF_INET
family of protocols.
.It Sy loopback
The
.Dv PF_LOCAL
protocol family.
.El
.It Ar protoname
The name of the protocol used for this transport.
Can currently be either
.Sy udp ,
.Sy tcp
or empty.
.It Ar device
This field is always empty in
.Fx .
.It Ar libraries
This field is always empty in
.Fx .
.El
.Pp
The order of entries in this file will determine which transport will
be preferred by the RPC library code, given a match on a specified
network type.
For example, if a sample network config file would look like this:
.Bd -literal -offset indent
udp6 tpi_clts v inet6 udp - -
tcp6 tpi_cots_ord v inet6 tcp - -
udp tpi_clts v inet udp - -
tcp tpi_cots_ord v inet tcp - -
rawip tpi_raw - inet - - -
local tpi_cots_ord - loopback - - -
.Ed
.Pp
then using the network type
.Sy udp
in calls to the RPC library function (see
.Xr rpc 3 )
will make the code first try
.Sy udp6 ,
and then
.Sy udp .
.Pp
.Xr getnetconfig 3
and associated functions will parse this file and return structures of
the following format:
.Bd -literal
struct netconfig {
char *nc_netid; /* Network ID */
unsigned long nc_semantics; /* Semantics (see below) */
unsigned long nc_flag; /* Flags (see below) */
char *nc_protofmly; /* Protocol family */
char *nc_proto; /* Protocol name */
char *nc_device; /* Network device pathname (unused) */
unsigned long nc_nlookups; /* Number of lookup libs (unused) */
char **nc_lookups; /* Names of the libraries (unused) */
unsigned long nc_unused[9]; /* reserved */
};
.Ed
.Sh FILES
.Bl -tag -width /etc/netconfig -compact
.It Pa /etc/netconfig
.El
.Sh SEE ALSO
.Xr getnetconfig 3 ,
.Xr getnetpath 3

View File

@ -41,6 +41,7 @@ static char sccsid[] = "@(#)netname.c 1.8 91/03/11 Copyr 1986 Sun Micro";
* the sun NIS domain architecture.
*/
#include "namespace.h"
#include <sys/param.h>
#include <rpc/rpc.h>
#include <rpc/rpc_com.h>
@ -54,6 +55,7 @@ static char sccsid[] = "@(#)netname.c 1.8 91/03/11 Copyr 1986 Sun Micro";
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "un-namespace.h"
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 256
@ -101,8 +103,8 @@ getnetname(name)
int
user2netname(netname, uid, domain)
char netname[MAXNETNAMELEN + 1];
uid_t uid;
char *domain;
const uid_t uid;
const char *domain;
{
char *dfltdom;
@ -126,8 +128,8 @@ user2netname(netname, uid, domain)
int
host2netname(netname, host, domain)
char netname[MAXNETNAMELEN + 1];
char *host;
char *domain;
const char *host;
const char *domain;
{
char *dfltdom;
char hostname[MAXHOSTNAMELEN+1];

View File

@ -38,6 +38,7 @@ static char sccsid[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro";
* will work with any unix system that has adopted the sun NIS domain
* architecture.
*/
#include "namespace.h"
#include <sys/param.h>
#include <rpc/rpc.h>
#include <rpc/rpc_com.h>
@ -52,6 +53,7 @@ static char sccsid[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro";
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "un-namespace.h"
static char *OPSYS = "unix";
static char *NETID = "netid.byname";

View File

@ -1,3 +1,5 @@
/* $NetBSD: pmap_clnt.c,v 1.16 2000/07/06 03:10:34 christos Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -27,6 +29,7 @@
* Mountain View, California 94043
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)pmap_clnt.c 2.2 88/08/01 4.0 RPCSRC";*/
@ -44,108 +47,74 @@ static char *rcsid = "$FreeBSD$";
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <rpc/rpc.h>
#include <rpc/pmap_prot.h>
#include <rpc/pmap_clnt.h>
#include <rpc/nettype.h>
#include <netinet/in.h>
#include "un-namespace.h"
static struct timeval timeout = { 5, 0 };
static struct timeval tottimeout = { 60, 0 };
#include <stdio.h>
#include <stdlib.h>
void clnt_perror();
#include "rpc_com.h"
#ifndef PORTMAPSOCK
#define PORTMAPSOCK "/var/run/portmapsock"
#endif
/*
* Set a mapping between program,version and port.
* Calls the pmap service remotely to do the mapping.
*/
bool_t
pmap_set(program, version, protocol, port)
u_long program;
u_long version;
int protocol;
u_short port;
pmap_set(u_long program, u_long version, int protocol, int port)
{
struct sockaddr_in myaddress;
int socket = -1;
register CLIENT *client;
struct pmap parms;
bool_t rslt;
struct stat st;
struct netbuf *na;
struct netconfig *nconf;
char buf[32];
/*
* Temporary hack for backwards compatibility. Eventually
* this test will go away and we'll use only the "unix" transport.
*/
if (stat(PORTMAPSOCK, &st) == 0 && st.st_mode & S_IFSOCK)
client = clnt_create(PORTMAPSOCK, PMAPPROG, PMAPVERS, "unix");
else {
if (get_myaddress(&myaddress) != 0)
return (FALSE);
myaddress.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
}
if (client == (CLIENT *)NULL)
return (FALSE);
parms.pm_prog = program;
parms.pm_vers = version;
parms.pm_prot = protocol;
parms.pm_port = port;
if (CLNT_CALL(client, PMAPPROC_SET, xdr_pmap, &parms, xdr_bool, &rslt,
tottimeout) != RPC_SUCCESS) {
clnt_perror(client, "Cannot register service");
if ((protocol != IPPROTO_UDP) && (protocol != IPPROTO_TCP)) {
return (FALSE);
}
CLNT_DESTROY(client);
if (socket != -1)
(void)_close(socket);
nconf = __rpc_getconfip(protocol == IPPROTO_UDP ? "udp" : "tcp");
if (nconf == NULL) {
return (FALSE);
}
snprintf(buf, sizeof buf, "0.0.0.0.%d.%d",
(((u_int32_t)port) >> 8) & 0xff, port & 0xff);
na = uaddr2taddr(nconf, buf);
if (na == NULL) {
freenetconfigent(nconf);
return (FALSE);
}
rslt = rpcb_set((rpcprog_t)program, (rpcvers_t)version, nconf, na);
free(na);
freenetconfigent(nconf);
return (rslt);
}
/*
* Remove the mapping between program,version and port.
* Remove the mapping between program, version and port.
* Calls the pmap service remotely to do the un-mapping.
*/
bool_t
pmap_unset(program, version)
u_long program;
u_long version;
pmap_unset(u_long program, u_long version)
{
struct sockaddr_in myaddress;
int socket = -1;
register CLIENT *client;
struct pmap parms;
bool_t rslt;
struct stat st;
struct netconfig *nconf;
bool_t udp_rslt = FALSE;
bool_t tcp_rslt = FALSE;
/*
* Temporary hack for backwards compatibility. Eventually
* this test will go away and we'll use only the "unix" transport.
*/
if (stat(PORTMAPSOCK, &st) == 0 && st.st_mode & S_IFSOCK)
client = clnt_create(PORTMAPSOCK, PMAPPROG, PMAPVERS, "unix");
else {
if (get_myaddress(&myaddress) != 0)
return (FALSE);
myaddress.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
nconf = __rpc_getconfip("udp");
if (nconf != NULL) {
udp_rslt = rpcb_unset((rpcprog_t)program, (rpcvers_t)version,
nconf);
freenetconfigent(nconf);
}
if (client == (CLIENT *)NULL)
return (FALSE);
parms.pm_prog = program;
parms.pm_vers = version;
parms.pm_port = parms.pm_prot = 0;
CLNT_CALL(client, PMAPPROC_UNSET, xdr_pmap, &parms, xdr_bool, &rslt,
tottimeout);
CLNT_DESTROY(client);
if (socket != -1)
(void)_close(socket);
return (rslt);
nconf = __rpc_getconfip("tcp");
if (nconf != NULL) {
tcp_rslt = rpcb_unset((rpcprog_t)program, (rpcvers_t)version,
nconf);
freenetconfigent(nconf);
}
/*
* XXX: The call may still succeed even if only one of the
* calls succeeded. This was the best that could be
* done for backward compatibility.
*/
return (tcp_rslt || udp_rslt);
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: pmap_getmaps.c,v 1.16 2000/07/06 03:10:34 christos Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -27,6 +29,7 @@
* Mountain View, California 94043
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)pmap_getmaps.c 2.2 88/08/01 4.0 RPCSRC";*/
@ -42,16 +45,21 @@ static char *rcsid = "$FreeBSD$";
*/
#include "namespace.h"
#include <rpc/rpc.h>
#include <rpc/pmap_prot.h>
#include <rpc/pmap_clnt.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <assert.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <rpc/rpc.h>
#include <rpc/pmap_prot.h>
#include <rpc/pmap_clnt.h>
#include "un-namespace.h"
#define NAMELEN 255
@ -65,25 +73,27 @@ struct pmaplist *
pmap_getmaps(address)
struct sockaddr_in *address;
{
struct pmaplist *head = (struct pmaplist *)NULL;
int socket = -1;
struct pmaplist *head = NULL;
int sock = -1;
struct timeval minutetimeout;
register CLIENT *client;
CLIENT *client;
assert(address != NULL);
minutetimeout.tv_sec = 60;
minutetimeout.tv_usec = 0;
address->sin_port = htons(PMAPPORT);
client = clnttcp_create(address, PMAPPROG,
PMAPVERS, &socket, 50, 500);
if (client != (CLIENT *)NULL) {
if (CLNT_CALL(client, PMAPPROC_DUMP, xdr_void, NULL, xdr_pmaplist,
&head, minutetimeout) != RPC_SUCCESS) {
PMAPVERS, &sock, 50, 500);
if (client != NULL) {
if (CLNT_CALL(client, (rpcproc_t)PMAPPROC_DUMP,
(xdrproc_t)xdr_void, NULL,
(xdrproc_t)xdr_pmaplist, &head, minutetimeout) !=
RPC_SUCCESS) {
clnt_perror(client, "pmap_getmaps rpc problem");
}
CLNT_DESTROY(client);
}
if (socket != -1)
(void)_close(socket);
address->sin_port = 0;
return (head);
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: pmap_getport.c,v 1.16 2000/07/06 03:10:34 christos Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -27,6 +29,7 @@
* Mountain View, California 94043
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)pmap_getport.c 2.2 88/08/01 4.0 RPCSRC";*/
@ -41,16 +44,21 @@ static char *rcsid = "$FreeBSD$";
*/
#include "namespace.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <assert.h>
#include <unistd.h>
#include <rpc/rpc.h>
#include <rpc/pmap_prot.h>
#include <rpc/pmap_clnt.h>
#include <sys/socket.h>
#include <net/if.h>
#include <unistd.h>
#include "un-namespace.h"
static struct timeval timeout = { 5, 0 };
static struct timeval tottimeout = { 60, 0 };
static const struct timeval timeout = { 5, 0 };
static const struct timeval tottimeout = { 60, 0 };
/*
* Find the mapped port for program,version.
@ -65,20 +73,24 @@ pmap_getport(address, program, version, protocol)
u_int protocol;
{
u_short port = 0;
int socket = -1;
register CLIENT *client;
int sock = -1;
CLIENT *client;
struct pmap parms;
assert(address != NULL);
address->sin_port = htons(PMAPPORT);
client = clntudp_bufcreate(address, PMAPPROG,
PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
if (client != (CLIENT *)NULL) {
PMAPVERS, timeout, &sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
if (client != NULL) {
parms.pm_prog = program;
parms.pm_vers = version;
parms.pm_prot = protocol;
parms.pm_port = 0; /* not needed or used */
if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms,
xdr_u_short, &port, tottimeout) != RPC_SUCCESS){
if (CLNT_CALL(client, (rpcproc_t)PMAPPROC_GETPORT,
(xdrproc_t)xdr_pmap,
&parms, (xdrproc_t)xdr_u_short, &port, tottimeout) !=
RPC_SUCCESS){
rpc_createerr.cf_stat = RPC_PMAPFAILURE;
clnt_geterr(client, &rpc_createerr.cf_error);
} else if (port == 0) {
@ -86,8 +98,6 @@ pmap_getport(address, program, version, protocol)
}
CLNT_DESTROY(client);
}
if (socket != -1)
(void)_close(socket);
address->sin_port = 0;
return (port);
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: pmap_prot.c,v 1.10 2000/01/22 22:19:18 mycroft Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -27,9 +29,10 @@
* Mountain View, California 94043
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)pmap_prot.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *sccsid = "@(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro";
static char *sccsid = "@(#)pmap_prot.c 2.1 88/07/29 4.0 RPCSRC";
static char *rcsid = "$FreeBSD$";
#endif
@ -40,9 +43,13 @@ static char *rcsid = "$FreeBSD$";
* Copyright (C) 1984, Sun Microsystems, Inc.
*/
#include "namespace.h"
#include <assert.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/pmap_prot.h>
#include "un-namespace.h"
bool_t
@ -51,6 +58,9 @@ xdr_pmap(xdrs, regs)
struct pmap *regs;
{
assert(xdrs != NULL);
assert(regs != NULL);
if (xdr_u_long(xdrs, &regs->pm_prog) &&
xdr_u_long(xdrs, &regs->pm_vers) &&
xdr_u_long(xdrs, &regs->pm_prot))

View File

@ -1,3 +1,5 @@
/* $NetBSD: pmap_prot2.c,v 1.14 2000/07/06 03:10:34 christos Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -27,9 +29,10 @@
* Mountain View, California 94043
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)pmap_prot2.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *sccsid = "@(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro";
static char *sccsid = "@(#)pmap_prot2.c 2.1 88/07/29 4.0 RPCSRC";
static char *rcsid = "$FreeBSD$";
#endif
@ -40,9 +43,13 @@ static char *rcsid = "$FreeBSD$";
* Copyright (C) 1984, Sun Microsystems, Inc.
*/
#include "namespace.h"
#include <assert.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/pmap_prot.h>
#include "un-namespace.h"
/*
@ -85,8 +92,8 @@ static char *rcsid = "$FreeBSD$";
*/
bool_t
xdr_pmaplist(xdrs, rp)
register XDR *xdrs;
register struct pmaplist **rp;
XDR *xdrs;
struct pmaplist **rp;
{
/*
* more_elements is pre-computed in case the direction is
@ -94,10 +101,15 @@ xdr_pmaplist(xdrs, rp)
* xdr_bool when the direction is XDR_DECODE.
*/
bool_t more_elements;
register int freeing = (xdrs->x_op == XDR_FREE);
register struct pmaplist **next = NULL;
int freeing;
struct pmaplist **next = NULL; /* pacify gcc */
while (TRUE) {
assert(xdrs != NULL);
assert(rp != NULL);
freeing = (xdrs->x_op == XDR_FREE);
for (;;) {
more_elements = (bool_t)(*rp != NULL);
if (! xdr_bool(xdrs, &more_elements))
return (FALSE);
@ -109,10 +121,23 @@ xdr_pmaplist(xdrs, rp)
* before we free the current object ...
*/
if (freeing)
next = &((*rp)->pml_next);
next = &((*rp)->pml_next);
if (! xdr_reference(xdrs, (caddr_t *)rp,
(u_int)sizeof(struct pmaplist), xdr_pmap))
(u_int)sizeof(struct pmaplist), (xdrproc_t)xdr_pmap))
return (FALSE);
rp = (freeing) ? next : &((*rp)->pml_next);
}
}
/*
* xdr_pmaplist_ptr() is specified to take a PMAPLIST *, but is identical in
* functionality to xdr_pmaplist().
*/
bool_t
xdr_pmaplist_ptr(xdrs, rp)
XDR *xdrs;
struct pmaplist *rp;
{
return xdr_pmaplist(xdrs, (struct pmaplist **)(void *)rp);
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: pmap_rmt.c,v 1.29 2000/07/06 03:10:34 christos Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -27,6 +29,7 @@
* Mountain View, California 94043
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)pmap_rmt.c 2.2 88/08/01 4.0 RPCSRC";*/
@ -42,24 +45,29 @@ static char *rcsid = "$FreeBSD$";
*/
#include "namespace.h"
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <rpc/rpc.h>
#include <rpc/pmap_prot.h>
#include <rpc/pmap_clnt.h>
#include <rpc/pmap_rmt.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include "un-namespace.h"
#define MAX_BROADCAST_SIZE 1400
static struct timeval timeout = { 3, 0 };
static const struct timeval timeout = { 3, 0 };
/*
* pmapper remote-call-service interface.
@ -69,7 +77,8 @@ static struct timeval timeout = { 3, 0 };
* programs to do a lookup and call in one step.
*/
enum clnt_stat
pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_ptr)
pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout,
port_ptr)
struct sockaddr_in *addr;
u_long prog, vers, proc;
xdrproc_t xdrargs, xdrres;
@ -77,15 +86,18 @@ pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_pt
struct timeval tout;
u_long *port_ptr;
{
int socket = -1;
register CLIENT *client;
int sock = -1;
CLIENT *client;
struct rmtcallargs a;
struct rmtcallres r;
enum clnt_stat stat;
assert(addr != NULL);
assert(port_ptr != NULL);
addr->sin_port = htons(PMAPPORT);
client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &socket);
if (client != (CLIENT *)NULL) {
client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &sock);
if (client != NULL) {
a.prog = prog;
a.vers = vers;
a.proc = proc;
@ -94,14 +106,13 @@ pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_pt
r.port_ptr = port_ptr;
r.results_ptr = resp;
r.xdr_results = xdrres;
stat = CLNT_CALL(client, PMAPPROC_CALLIT, xdr_rmtcall_args, &a,
xdr_rmtcallres, &r, tout);
stat = CLNT_CALL(client, (rpcproc_t)PMAPPROC_CALLIT,
(xdrproc_t)xdr_rmtcall_args, &a, (xdrproc_t)xdr_rmtcallres,
&r, tout);
CLNT_DESTROY(client);
} else {
stat = RPC_FAILED;
}
if (socket != -1)
(void)_close(socket);
addr->sin_port = 0;
return (stat);
}
@ -113,11 +124,14 @@ pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_pt
*/
bool_t
xdr_rmtcall_args(xdrs, cap)
register XDR *xdrs;
register struct rmtcallargs *cap;
XDR *xdrs;
struct rmtcallargs *cap;
{
u_int lenposition, argposition, position;
assert(xdrs != NULL);
assert(cap != NULL);
if (xdr_u_long(xdrs, &(cap->prog)) &&
xdr_u_long(xdrs, &(cap->vers)) &&
xdr_u_long(xdrs, &(cap->proc))) {
@ -144,275 +158,19 @@ xdr_rmtcall_args(xdrs, cap)
*/
bool_t
xdr_rmtcallres(xdrs, crp)
register XDR *xdrs;
register struct rmtcallres *crp;
XDR *xdrs;
struct rmtcallres *crp;
{
caddr_t port_ptr;
port_ptr = (caddr_t)crp->port_ptr;
assert(xdrs != NULL);
assert(crp != NULL);
port_ptr = (caddr_t)(void *)crp->port_ptr;
if (xdr_reference(xdrs, &port_ptr, sizeof (u_long),
xdr_u_long) && xdr_u_long(xdrs, &crp->resultslen)) {
crp->port_ptr = (u_long *)port_ptr;
(xdrproc_t)xdr_u_long) && xdr_u_long(xdrs, &crp->resultslen)) {
crp->port_ptr = (u_long *)(void *)port_ptr;
return ((*(crp->xdr_results))(xdrs, crp->results_ptr));
}
return (FALSE);
}
/*
* The following is kludged-up support for simple rpc broadcasts.
* Someday a large, complicated system will replace these trivial
* routines which only support udp/ip .
*/
static int
getbroadcastnets(addrs, sock, buf)
struct in_addr *addrs;
int sock; /* any valid socket will do */
char *buf; /* why allocxate more when we can use existing... */
{
struct ifconf ifc;
struct ifreq ifreq, *ifr;
struct sockaddr_in *sin;
struct in_addr addr;
char *cp, *cplim;
int n, i = 0;
ifc.ifc_len = UDPMSGSIZE;
ifc.ifc_buf = buf;
if (_ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
perror("broadcast: ioctl (get interface configuration)");
return (0);
}
#define max(a, b) (a > b ? a : b)
#define size(p) max((p).sa_len, sizeof(p))
cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */
for (cp = buf; cp < cplim;
cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) {
ifr = (struct ifreq *)cp;
if (ifr->ifr_addr.sa_family != AF_INET)
continue;
memcpy(&ifreq, ifr, sizeof(ifreq));
if (_ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
perror("broadcast: ioctl (get interface flags)");
continue;
}
if ((ifreq.ifr_flags & IFF_BROADCAST) &&
(ifreq.ifr_flags & IFF_UP)) {
sin = (struct sockaddr_in *)&ifr->ifr_addr;
#ifdef SIOCGIFBRDADDR /* 4.3BSD */
if (_ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
addr =
inet_makeaddr(inet_netof(sin->sin_addr),
INADDR_ANY);
} else {
addr = ((struct sockaddr_in*)
&ifreq.ifr_addr)->sin_addr;
}
#else /* 4.2 BSD */
addr = inet_makeaddr(inet_netof(sin->sin_addr),
INADDR_ANY);
#endif
for (n=i-1; n>=0; n--) {
if (addr.s_addr == addrs[n].s_addr)
break;
}
if (n<0) {
addrs[i++] = addr;
}
}
}
return (i);
}
typedef bool_t (*resultproc_t)();
enum clnt_stat
clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
u_long prog; /* program number */
u_long vers; /* version number */
u_long proc; /* procedure number */
xdrproc_t xargs; /* xdr routine for args */
caddr_t argsp; /* pointer to args */
xdrproc_t xresults; /* xdr routine for results */
caddr_t resultsp; /* pointer to results */
resultproc_t eachresult; /* call with each result obtained */
{
enum clnt_stat stat;
AUTH *unix_auth = authunix_create_default();
XDR xdr_stream;
register XDR *xdrs = &xdr_stream;
int outlen, inlen, fromlen, nets;
register int sock;
int on = 1;
fd_set *fds, readfds;
register int i;
bool_t done = FALSE;
register u_long xid;
u_long port;
struct in_addr addrs[20];
struct sockaddr_in baddr, raddr; /* broadcast and response addresses */
struct rmtcallargs a;
struct rmtcallres r;
struct rpc_msg msg;
struct timeval t, tv;
char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE];
static u_int32_t disrupt;
if (disrupt == 0)
disrupt = (u_int32_t)(long)resultsp;
/*
* initialization: create a socket, a broadcast address, and
* preserialize the arguments into a send buffer.
*/
if ((sock = _socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
perror("Cannot create socket for broadcast rpc");
stat = RPC_CANTSEND;
goto done_broad;
}
#ifdef SO_BROADCAST
if (_setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
perror("Cannot set socket option SO_BROADCAST");
stat = RPC_CANTSEND;
goto done_broad;
}
#endif /* def SO_BROADCAST */
if (sock + 1 > FD_SETSIZE) {
int bytes = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
fds = (fd_set *)malloc(bytes);
if (fds == NULL) {
stat = RPC_CANTSEND;
goto done_broad;
}
memset(fds, 0, bytes);
} else {
fds = &readfds;
FD_ZERO(fds);
}
nets = getbroadcastnets(addrs, sock, inbuf);
memset(&baddr, 0, sizeof (baddr));
baddr.sin_len = sizeof(struct sockaddr_in);
baddr.sin_family = AF_INET;
baddr.sin_port = htons(PMAPPORT);
baddr.sin_addr.s_addr = htonl(INADDR_ANY);
(void)gettimeofday(&t, (struct timezone *)0);
msg.rm_xid = xid = (++disrupt) ^ getpid() ^ t.tv_sec ^ t.tv_usec;
t.tv_usec = 0;
msg.rm_direction = CALL;
msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
msg.rm_call.cb_prog = PMAPPROG;
msg.rm_call.cb_vers = PMAPVERS;
msg.rm_call.cb_proc = PMAPPROC_CALLIT;
msg.rm_call.cb_cred = unix_auth->ah_cred;
msg.rm_call.cb_verf = unix_auth->ah_verf;
a.prog = prog;
a.vers = vers;
a.proc = proc;
a.xdr_args = xargs;
a.args_ptr = argsp;
r.port_ptr = &port;
r.xdr_results = xresults;
r.results_ptr = resultsp;
xdrmem_create(xdrs, outbuf, MAX_BROADCAST_SIZE, XDR_ENCODE);
if ((! xdr_callmsg(xdrs, &msg)) || (! xdr_rmtcall_args(xdrs, &a))) {
stat = RPC_CANTENCODEARGS;
goto done_broad;
}
outlen = (int)xdr_getpos(xdrs);
xdr_destroy(xdrs);
/*
* Basic loop: broadcast a packet and wait a while for response(s).
* The response timeout grows larger per iteration.
*
* XXX This will loop about 5 times the stop. If there are
* lots of signals being received by the process it will quit
* send them all in one quick burst, not paying attention to
* the intended function of sending them slowly over half a
* minute or so
*/
for (t.tv_sec = 4; t.tv_sec <= 14; t.tv_sec += 2) {
for (i = 0; i < nets; i++) {
baddr.sin_addr = addrs[i];
if (_sendto(sock, outbuf, outlen, 0,
(struct sockaddr *)&baddr,
sizeof (struct sockaddr)) != outlen) {
perror("Cannot send broadcast packet");
stat = RPC_CANTSEND;
goto done_broad;
}
}
if (eachresult == NULL) {
stat = RPC_SUCCESS;
goto done_broad;
}
recv_again:
msg.acpted_rply.ar_verf = _null_auth;
msg.acpted_rply.ar_results.where = (caddr_t)&r;
msg.acpted_rply.ar_results.proc = xdr_rmtcallres;
/* XXX we know the other bits are still clear */
FD_SET(sock, fds);
tv = t; /* for _select() that copies back */
switch (_select(sock + 1, fds, NULL, NULL, &tv)) {
case 0: /* timed out */
stat = RPC_TIMEDOUT;
continue;
case -1: /* some kind of error */
if (errno == EINTR)
goto recv_again;
perror("Broadcast select problem");
stat = RPC_CANTRECV;
goto done_broad;
} /* end of select results switch */
try_again:
fromlen = sizeof(struct sockaddr);
inlen = _recvfrom(sock, inbuf, UDPMSGSIZE, 0,
(struct sockaddr *)&raddr, &fromlen);
if (inlen < 0) {
if (errno == EINTR)
goto try_again;
perror("Cannot receive reply to broadcast");
stat = RPC_CANTRECV;
goto done_broad;
}
if (inlen < sizeof(u_int32_t))
goto recv_again;
/*
* see if reply transaction id matches sent id.
* If so, decode the results.
*/
xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE);
if (xdr_replymsg(xdrs, &msg)) {
if ((msg.rm_xid == xid) &&
(msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
(msg.acpted_rply.ar_stat == SUCCESS)) {
raddr.sin_port = htons((u_short)port);
done = (*eachresult)(resultsp, &raddr);
}
/* otherwise, we just ignore the errors ... */
}
xdrs->x_op = XDR_FREE;
msg.acpted_rply.ar_results.proc = xdr_void;
(void)xdr_replymsg(xdrs, &msg);
(void)(*xresults)(xdrs, resultsp);
xdr_destroy(xdrs);
if (done) {
stat = RPC_SUCCESS;
goto done_broad;
} else {
goto recv_again;
}
}
done_broad:
if (fds != &readfds)
free(fds);
if (sock >= 0)
(void)_close(sock);
AUTH_DESTROY(unix_auth);
return (stat);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,36 +1,60 @@
.\" $NetBSD: rpc.5,v 1.3 2000/06/15 20:05:54 fvdl Exp $
.\" $FreeBSD$
.\" @(#)rpc.5 2.2 88/08/03 4.0 RPCSRC; from 1.4 87/11/27 SMI;
.Dd September 26, 1985
.\" $FreeBSD$
.\" @(#)rpc.4 1.17 93/08/30 SMI; from SVr4
.\" Copyright 1989 AT&T
.Dd December 10, 1991
.Dt RPC 5
.Os
.Sh NAME
.Nm rpc
.Nd rpc program number data base
.Sh SYNOPSIS
/etc/rpc
.Pa /etc/rpc
.Sh DESCRIPTION
The
.Pa /etc/rpc
.Nm
file contains user readable names that
can be used in place of rpc program numbers.
Each line has the following information:
can be used in place of RPC program numbers.
For each RPC program a single line should be present
with the following information:
.Pp
.Bl -bullet -compact
.Bl -enum -compact
.It
name of server for the rpc program
name of the RPC program
.It
rpc program number
RPC program number
.It
aliases
.El
.Pp
Items are separated by any number of blanks and/or
tab characters.
A ``#'' indicates the beginning of a comment; characters up to the end of
A hash
.Pq Dq Li #
indicates the beginning of a comment; characters up to the end of
the line are not interpreted by routines which search the file.
.Sh EXAMPLES
Below is an example of an RPC database:
.Bd -literal
#
# rpc
#
rpcbind 100000 portmap sunrpc portmapper
rusersd 100002 rusers
nfs 100003 nfsprog
mountd 100005 mount showmount
walld 100008 rwall shutdown
sprayd 100012 spray
llockmgr 100020
nlockmgr 100021
status 100024
bootparam 100026
keyserv 100029 keyserver
.Ed
.Sh FILES
.Bl -tag -compact -width /etc/rpc
.It Pa /etc/rpc
.Bl -tag -width /etc/nsswitch.conf -compact
.It Pa /etc/nsswitch.conf
.El
.Sh "SEE ALSO"
.Sh SEE ALSO
.Xr getrpcent 3

View File

@ -1,3 +1,5 @@
/* $NetBSD: rpc_callmsg.c,v 1.16 2000/07/14 08:40:42 fvdl Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -27,9 +29,10 @@
* Mountain View, California 94043
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)rpc_callmsg.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *sccsid = "@(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro";
static char *sccsid = "@(#)rpc_callmsg.c 2.1 88/07/29 4.0 RPCSRC";
static char *rcsid = "$FreeBSD$";
#endif
@ -40,21 +43,27 @@ static char *rcsid = "$FreeBSD$";
*
*/
#include <sys/param.h>
#include "namespace.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <rpc/rpc.h>
#include "un-namespace.h"
/*
* XDR a call message
*/
bool_t
xdr_callmsg(xdrs, cmsg)
register XDR *xdrs;
register struct rpc_msg *cmsg;
XDR *xdrs;
struct rpc_msg *cmsg;
{
register int32_t *buf;
register struct opaque_auth *oa;
int32_t *buf;
struct opaque_auth *oa;
assert(xdrs != NULL);
assert(cmsg != NULL);
if (xdrs->x_op == XDR_ENCODE) {
if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) {
@ -68,30 +77,30 @@ xdr_callmsg(xdrs, cmsg)
+ 2 * BYTES_PER_XDR_UNIT
+ RNDUP(cmsg->rm_call.cb_verf.oa_length));
if (buf != NULL) {
IXDR_PUT_LONG(buf, cmsg->rm_xid);
IXDR_PUT_INT32(buf, cmsg->rm_xid);
IXDR_PUT_ENUM(buf, cmsg->rm_direction);
if (cmsg->rm_direction != CALL) {
return (FALSE);
}
IXDR_PUT_LONG(buf, cmsg->rm_call.cb_rpcvers);
IXDR_PUT_INT32(buf, cmsg->rm_call.cb_rpcvers);
if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
return (FALSE);
}
IXDR_PUT_LONG(buf, cmsg->rm_call.cb_prog);
IXDR_PUT_LONG(buf, cmsg->rm_call.cb_vers);
IXDR_PUT_LONG(buf, cmsg->rm_call.cb_proc);
IXDR_PUT_INT32(buf, cmsg->rm_call.cb_prog);
IXDR_PUT_INT32(buf, cmsg->rm_call.cb_vers);
IXDR_PUT_INT32(buf, cmsg->rm_call.cb_proc);
oa = &cmsg->rm_call.cb_cred;
IXDR_PUT_ENUM(buf, oa->oa_flavor);
IXDR_PUT_LONG(buf, oa->oa_length);
IXDR_PUT_INT32(buf, oa->oa_length);
if (oa->oa_length) {
memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);
memmove(buf, oa->oa_base, oa->oa_length);
buf += RNDUP(oa->oa_length) / sizeof (int32_t);
}
oa = &cmsg->rm_call.cb_verf;
IXDR_PUT_ENUM(buf, oa->oa_flavor);
IXDR_PUT_LONG(buf, oa->oa_length);
IXDR_PUT_INT32(buf, oa->oa_length);
if (oa->oa_length) {
memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);
memmove(buf, oa->oa_base, oa->oa_length);
/* no real need....
buf += RNDUP(oa->oa_length) / sizeof (int32_t);
*/
@ -102,28 +111,30 @@ xdr_callmsg(xdrs, cmsg)
if (xdrs->x_op == XDR_DECODE) {
buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT);
if (buf != NULL) {
cmsg->rm_xid = IXDR_GET_LONG(buf);
cmsg->rm_xid = IXDR_GET_U_INT32(buf);
cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type);
if (cmsg->rm_direction != CALL) {
return (FALSE);
}
cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG(buf);
cmsg->rm_call.cb_rpcvers = IXDR_GET_U_INT32(buf);
if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
return (FALSE);
}
cmsg->rm_call.cb_prog = IXDR_GET_LONG(buf);
cmsg->rm_call.cb_vers = IXDR_GET_LONG(buf);
cmsg->rm_call.cb_proc = IXDR_GET_LONG(buf);
cmsg->rm_call.cb_prog = IXDR_GET_U_INT32(buf);
cmsg->rm_call.cb_vers = IXDR_GET_U_INT32(buf);
cmsg->rm_call.cb_proc = IXDR_GET_U_INT32(buf);
oa = &cmsg->rm_call.cb_cred;
oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
oa->oa_length = IXDR_GET_LONG(buf);
oa->oa_length = (u_int)IXDR_GET_U_INT32(buf);
if (oa->oa_length) {
if (oa->oa_length > MAX_AUTH_BYTES) {
return (FALSE);
}
if (oa->oa_base == NULL) {
oa->oa_base = (caddr_t)
mem_alloc(oa->oa_length);
mem_alloc(oa->oa_length);
if (oa->oa_base == NULL)
return (FALSE);
}
buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
if (buf == NULL) {
@ -132,7 +143,7 @@ xdr_callmsg(xdrs, cmsg)
return (FALSE);
}
} else {
memcpy(oa->oa_base, (caddr_t)buf,
memmove(oa->oa_base, buf,
oa->oa_length);
/* no real need....
buf += RNDUP(oa->oa_length) /
@ -149,7 +160,7 @@ xdr_callmsg(xdrs, cmsg)
}
} else {
oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
oa->oa_length = IXDR_GET_LONG(buf);
oa->oa_length = (u_int)IXDR_GET_U_INT32(buf);
}
if (oa->oa_length) {
if (oa->oa_length > MAX_AUTH_BYTES) {
@ -157,7 +168,9 @@ xdr_callmsg(xdrs, cmsg)
}
if (oa->oa_base == NULL) {
oa->oa_base = (caddr_t)
mem_alloc(oa->oa_length);
mem_alloc(oa->oa_length);
if (oa->oa_base == NULL)
return (FALSE);
}
buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
if (buf == NULL) {
@ -166,7 +179,7 @@ xdr_callmsg(xdrs, cmsg)
return (FALSE);
}
} else {
memcpy(oa->oa_base, (caddr_t)buf,
memmove(oa->oa_base, buf,
oa->oa_length);
/* no real need...
buf += RNDUP(oa->oa_length) /
@ -187,7 +200,6 @@ xdr_callmsg(xdrs, cmsg)
xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers)) &&
xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_proc)) &&
xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) )
return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf)));
return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf)));
return (FALSE);
}

View File

@ -0,0 +1,95 @@
.\" @(#)rpc_clnt_auth.3n 1.21 93/05/07 SMI; from SVr4
.\" Copyright 1989 AT&T
.\" @(#)rpc_clnt_auth 1.4 89/07/20 SMI;
.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved.
.\" $NetBSD: rpc_clnt_auth.3,v 1.1 2000/06/03 09:29:50 fvdl Exp $
.\" $FreeBSD$
.Dd May 7, 1993
.Dt RPC_CLNT_AUTH 3
.Os
.Sh NAME
.Nm auth_destroy ,
.Nm authnone_create ,
.Nm authsys_create ,
.Nm authsys_create_default
.Nd library routines for client side remote procedure call authentication
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.Fd #include <rpc/rpc.h>
.Ft "void"
.Fn auth_destroy "AUTH *auth"
.Ft "AUTH *"
.Fn authnone_create "void"
.Ft "AUTH *"
.Fn authsys_create "const char *host" "const uid_t uid" "const gid_t gid" "const int len" "const gid_t *aup_gids"
.Ft "AUTH *"
.Fn authsys_create_default "void"
.Sh DESCRIPTION
These routines are part of the
RPC library that allows C language programs to make procedure
calls on other machines across the network,
with desired authentication.
.Pp
These routines are normally called after creating the
.Vt CLIENT
handle.
The
.Va cl_auth
field of the
.Vt CLIENT
structure should be initialized by the
.Vt AUTH
structure returned by some of the following routines.
The client's authentication information
is passed to the server when the
RPC
call is made.
.Pp
Only the
.Dv NULL
and the
.Dv SYS
style of authentication is discussed here.
.Sh Routines
.Bl -tag -width authsys_create_default()
.It Fn auth_destroy
A function macro that destroys the authentication
information associated with
.Fa auth .
Destruction usually involves deallocation
of private data structures.
The use of
.Fn auth
is undefined after calling
.Fn auth_destroy .
.It Fn authnone_create
Create and return an RPC
authentication handle that passes nonusable
authentication information with each remote procedure call.
This is the default authentication used by RPC.
.It Fn authsys_create
Create and return an RPC authentication handle that contains
.Dv AUTH_SYS
authentication information.
The parameter
.Fa host
is the name of the machine on which the information was
created;
.Fa uid
is the user's user ID;
.Fa gid
is the user's current group ID;
.Fa len
and
.Fa aup_gids
refer to a counted array of groups to which the user belongs.
.It Fn authsys_create_default
Call
.Fn authsys_create
with the appropriate parameters.
.El
.Sh SEE ALSO
.Xr rpc 3 ,
.Xr rpc_clnt_calls 3 ,
.Xr rpc_clnt_create 3

View File

@ -0,0 +1,302 @@
.\" @(#)rpc_clnt_calls.3n 1.30 93/08/31 SMI; from SVr4
.\" Copyright 1989 AT&T
.\" @(#)rpc_clnt_calls 1.4 89/07/20 SMI;
.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved.
.\" $FreeBSD$
.Dd May 7, 1993
.Dt RPC_CLNT_CALLS 3
.Os
.Sh NAME
.Nm rpc_clnt_calls ,
.Nm clnt_call ,
.Nm clnt_freeres ,
.Nm clnt_geterr ,
.Nm clnt_perrno ,
.Nm clnt_perror ,
.Nm clnt_sperrno ,
.Nm clnt_sperror ,
.Nm rpc_broadcast ,
.Nm rpc_broadcast_exp ,
.Nm rpc_call
.Nd library routines for client side calls
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.Fd #include <rpc/rpc.h>
.Ft "enum clnt_stat"
.Fn clnt_call "CLIENT *clnt" "const rpcproc_t procnum" "const xdrproc_t inproc" "const caddr_t in" "const xdrproc_t outproc" "caddr_t out" "const struct timeval tout"
.Ft bool_t
.Fn clnt_freeres "CLIENT *clnt" "const xdrproc_t outproc" "caddr_t out"
.Ft void
.Fn clnt_geterr "const CLIENT * clnt" "struct rpc_err * errp"
.Ft void
.Fn clnt_perrno "const enum clnt_stat stat"
.Ft void
.Fn clnt_perror "const CLIENT * clnt" "const char *s"
.Ft "char *"
.Fn clnt_sperrno "const enum clnt_stat stat"
.Ft "char *"
.Fn clnt_sperror "const CLIENT *clnt" "const char * s"
.Ft "enum clnt_stat"
.Fo rpc_broadcast
.Fa "const rpcprog_t prognum" "const rpcvers_t versnum"
.Fa "const rpcproc_t procnum" "const xdrproc_t inproc"
.Fa "const caddr_t in" "const xdrproc_t outproc" "caddr_t out"
.Fa "const resultproc_t eachresult" "const char *nettype"
.Fc
.Ft "enum clnt_stat"
.Fo rpc_broadcast_exp
.Fa "rpcprog_t prognum" "const rpcvers_t versnum"
.Fa "const rpcproc_t procnum" "const xdrproc_t xargs"
.Fa "caddr_t argsp" "const xdrproc_t xresults"
.Fa "caddr_t resultsp" "const int inittime" "const int waittime"
.Fa "const resultproc_t eachresult" "const char * nettype"
.Fc
.Ft "enum clnt_stat"
.Fo rpc_call
.Fa "const char *host" "const rpcprog_t prognum"
.Fa "const rpcvers_t versnum" "const rpcproc_t procnum"
.Fa "const xdrproc_t inproc" "const char *in"
.Fa "const xdrproc_t outproc" "char *out" "const char *nettype"
.Fc
.Sh DESCRIPTION
RPC library routines allow C language programs to make procedure
calls on other machines across the network.
First, the client calls a procedure to send a request to the server.
Upon receipt of the request, the server calls a dispatch routine
to perform the requested service, and then sends back a reply.
.Pp
The
.Fn clnt_call ,
.Fn rpc_call ,
and
.Fn rpc_broadcast
routines handle the client side of the procedure call.
The remaining routines deal with error handling in the case of errors.
.Pp
Some of the routines take a
.Vt CLIENT
handle as one of the parameters.
A
.Vt CLIENT
handle can be created by an RPC creation routine such as
.Fn clnt_create
(see
.Xr rpc_clnt_create 3 ) .
.Pp
These routines are safe for use in multithreaded applications.
.Vt CLIENT
handles can be shared between threads, however in this implementation
requests by different threads are serialized (that is, the first request will
receive its results before the second request is sent).
.Sh Routines
See
.Xr rpc 3
for the definition of the
.Vt CLIENT
data structure.
.Bl -tag -width XXXXX
.It Fn clnt_call
A function macro that calls the remote procedure
.Fa procnum
associated with the client handle,
.Fa clnt ,
which is obtained with an RPC
client creation routine such as
.Fn clnt_create
(see
.Xr rpc_clnt_create 3 ) .
The parameter
.Fa inproc
is the XDR function used to encode the procedure's parameters, and
.Fa outproc
is the XDR function used to decode the procedure's results;
.Fa in
is the address of the procedure's argument(s), and
.Fa out
is the address of where to place the result(s).
.Fa tout
is the time allowed for results to be returned, which is overridden by
a time-out set explicitly through
.Fn clnt_control ,
see
.Xr rpc_clnt_create 3 .
If the remote call succeeds, the status returned is
.Dv RPC_SUCCESS ,
otherwise an appropriate status is returned.
.It Fn clnt_freeres
A function macro that frees any data allocated by the
RPC/XDR system when it decoded the results of an RPC call.
The parameter
.Fa out
is the address of the results, and
.Fa outproc
is the XDR routine describing the results.
This routine returns 1 if the results were successfully freed,
and 0 otherwise.
.It Fn clnt_geterr
A function macro that copies the error structure out of the client
handle to the structure at address
.Fa errp .
.It Fn clnt_perrno
Print a message to standard error corresponding
to the condition indicated by
.Fa stat .
A newline is appended.
Normally used after a procedure call fails for a routine
for which a client handle is not needed, for instance
.Fn rpc_call .
.It Fn clnt_perror
Print a message to the standard error indicating why an
RPC call failed;
.Fa clnt
is the handle used to do the call.
The message is prepended with string
.Fa s
and a colon.
A newline is appended.
Normally used after a remote procedure call fails
for a routine which requires a client handle,
for instance
.Fn clnt_call .
.It Fn clnt_sperrno
Take the same arguments as
.Fn clnt_perrno ,
but instead of sending a message to the standard error
indicating why an RPC
call failed, return a pointer to a string which contains the message.
.Fn clnt_sperrno
is normally used instead of
.Fn clnt_perrno
when the program does not have a standard error (as a program
running as a server quite likely does not), or if the programmer
does not want the message to be output with
.Fn printf
(see
.Xr printf 3 ) ,
or if a message format different than that supported by
.Fn clnt_perrno
is to be used.
Note:
unlike
.Fn clnt_sperror
and
.Fn clnt_spcreaterror
(see
.Xr rpc_clnt_create 3 ) ,
.Fn clnt_sperrno
does not return pointer to static data so the
result will not get overwritten on each call.
.It Fn clnt_sperror
Like
.Fn clnt_perror ,
except that (like
.Fn clnt_sperrno )
it returns a string instead of printing to standard error.
However,
.Fn clnt_sperror
does not append a newline at the end of the message.
Warning:
returns pointer to a buffer that is overwritten
on each call.
.It Fn rpc_broadcast
Like
.Fn rpc_call ,
except the call message is broadcast to
all the connectionless transports specified by
.Fa nettype .
If
.Fa nettype
is
.Dv NULL ,
it defaults to
.Qq netpath .
Each time it receives a response,
this routine calls
.Fn eachresult ,
whose form is:
.Ft bool_t
.Fn eachresult "caddr_t out" "const struct netbuf * addr" "const struct netconfig * netconf"
where
.Fa out
is the same as
.Fa out
passed to
.Fn rpc_broadcast ,
except that the remote procedure's output is decoded there;
.Fa addr
points to the address of the machine that sent the results, and
.Fa netconf
is the netconfig structure of the transport on which the remote
server responded.
If
.Fn eachresult
returns 0,
.Fn rpc_broadcast
waits for more replies;
otherwise it returns with appropriate status.
Warning:
broadcast file descriptors are limited in size to the
maximum transfer size of that transport.
For Ethernet, this value is 1500 bytes.
.Fn rpc_broadcast
uses
.Dv AUTH_SYS
credentials by default (see
.Xr rpc_clnt_auth 3 ) .
.It Fn rpc_broadcast_exp
Like
.Fn rpc_broadcast ,
except that the initial timeout,
.Fa inittime
and the maximum timeout,
.Fa waittime
are specified in milliseconds.
.Fa inittime
is the initial time that
.Fn rpc_broadcast_exp
waits before resending the request.
After the first resend, the re-transmission interval
increases exponentially until it exceeds
.Fa waittime .
.It Fn rpc_call
Call the remote procedure associated with
.Fa prognum ,
.Fa versnum ,
and
.Fa procnum
on the machine,
.Fa host .
The parameter
.Fa inproc
is used to encode the procedure's parameters, and
.Fa outproc
is used to decode the procedure's results;
.Fa in
is the address of the procedure's argument(s), and
.Fa out
is the address of where to place the result(s).
.Fa nettype
can be any of the values listed on
.Xr rpc 3 .
This routine returns
.Dv RPC_SUCCESS
if it succeeds,
or an appropriate status is returned.
Use the
.Fn clnt_perrno
routine to translate failure status into error messages.
Warning:
.Fn rpc_call
uses the first available transport belonging
to the class
.Fa nettype ,
on which it can create a connection.
You do not have control of timeouts or authentication
using this routine.
.El
.Sh SEE ALSO
.Xr printf 3 ,
.Xr rpc 3 ,
.Xr rpc_clnt_auth 3 ,
.Xr rpc_clnt_create 3

View File

@ -0,0 +1,437 @@
.\" @(#)rpc_clnt_create.3n 1.36 93/08/31 SMI; from SVr4
.\" Copyright 1989 AT&T
.\" @(#)rpc_clnt_create 1.5 89/07/24 SMI;
.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved.
.\" $NetBSD: rpc_clnt_create.3,v 1.2 2000/06/20 00:53:08 fvdl Exp $
.\" $FreeBSD$
.Dd May 7, 1993
.Dt RPC_CLNT_CREATE 3
.Os
.Sh NAME
.Nm rpc_clnt_create ,
.Nm clnt_control ,
.Nm clnt_create ,
.Nm clnt_create_vers ,
.Nm clnt_destroy ,
.Nm clnt_dg_create ,
.Nm clnt_pcreateerror ,
.Nm clnt_raw_create ,
.Nm clnt_spcreateerror ,
.Nm clnt_tli_create ,
.Nm clnt_tp_create ,
.Nm clnt_vc_create ,
.Nm rpc_createerr
.Nd "library routines for dealing with creation and manipulation of"
.Vt CLIENT
handles
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.Fd #include <rpc/rpc.h>
.Ft bool_t
.Fn clnt_control "CLIENT *clnt" "const u_int req" "char *info"
.Ft "CLIENT *"
.Fn clnt_create "const char * host" "const rpcprog_t prognum" "const rpcvers_t versnum" "const char *nettype"
.Ft "CLIENT *"
.Fn clnt_create_vers "const char * host" "const rpcprog_t prognum" "rpcvers_t *vers_outp" "const rpcvers_t vers_low" "const rpcvers_t vers_high" "char *nettype"
.Ft void
.Fn clnt_destroy "CLIENT *" "clnt"
.Ft "CLIENT *"
.Fn clnt_dg_create "const int fildes" "const struct netbuf *svcaddr" "const rpcprog_t prognum" "const rpcvers_t versnum" "const u_int sendsz" "const u_int recvsz"
.Ft void
.Fn clnt_pcreateerror "const char *s"
.Ft "char *"
.Fn clnt_spcreateerror "const char *s"
.Ft "CLIENT *"
.Fn clnt_raw_create "const rpcprog_t prognum" "const rpcvers_t versnum"
.Ft "CLIENT *"
.Fn clnt_tli_create "const int fildes" "const struct netconfig *netconf" "const struct netbuf *svcaddr" "const rpcprog_t prognum" "const rpcvers_t versnum" "const u_int sendsz" "const u_int recvsz"
.Ft "CLIENT *"
.Fn clnt_tp_create "const char * host" "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf"
.Ft "CLIENT *"
.Fn clnt_vc_create "const int fildes" "const struct netbuf *svcaddr" "const rpcprog_t prognum" "const rpcvers_t versnum" "const u_int sendsz" "const u_int recvsz"
.Sh DESCRIPTION
RPC library routines allow C language programs to make procedure
calls on other machines across the network.
First a
.Vt CLIENT
handle is created and then the client calls a procedure to send a
request to the server.
On receipt of the request, the server calls a dispatch routine
to perform the requested service, and then sends a reply.
.Sh Routines
.Bl -tag -width YYYYYYY
.It Fn clnt_control
A function macro to change or retrieve various information
about a client object.
.Fa req
indicates the type of operation, and
.Fa info
is a pointer to the information.
For both connectionless and connection-oriented transports,
the supported values of
.Fa req
and their argument types and what they do are:
.Bl -column "CLSET_FD_NCLOSE" "struct timeval *" "set total timeout"
.It Dv CLSET_TIMEOUT Ta "struct timeval *" Ta "set total timeout"
.It Dv CLGET_TIMEOUT Ta "struct timeval *" Ta "get total timeout"
.El
.Pp
Note:
if you set the timeout using
.Fn clnt_control ,
the timeout argument passed by
.Fn clnt_call
is ignored in all subsequent calls.
.Pp
Note:
If you set the timeout value to 0,
.Fn clnt_control
immediately returns an error
.Pq Dv RPC_TIMEDOUT .
Set the timeout parameter to 0 for batching calls.
.Bl -column CLSET_FD_NCLOSE "struct timeval *" "do not close fd on destroy"
.It Dv CLGET_SVC_ADDR Ta "struct netbuf *" Ta "get servers address"
.It Dv CLGET_FD Ta "int *" Ta "get fd from handle"
.It Dv CLSET_FD_CLOSE Ta "void" Ta "close fd on destroy"
.It Dv CLSET_FD_NCLOSE Ta void Ta "don't close fd on destroy"
.It Dv CLGET_VERS Ta "unsigned long *" Ta "get RPC program version"
.It Dv CLSET_VERS Ta "unsigned long *" Ta "set RPC program version"
.It Dv CLGET_XID Ta "unsigned long *" Ta "get XID of previous call"
.It Dv CLSET_XID Ta "unsigned long *" Ta "set XID of next call"
.El
.Pp
The following operations are valid for connectionless transports only:
.Bl -column CLSET_RETRY_TIMEOUT "struct timeval *" "set total timeout"
.It Dv CLSET_RETRY_TIMEOUT Ta "struct timeval *" Ta "set the retry timeout"
.It Dv CLGET_RETRY_TIMEOUT Ta "struct timeval *" Ta "get the retry timeout"
.El
.Pp
The retry timeout is the time that RPC
waits for the server to reply before retransmitting the request.
.Fn clnt_control
returns
.Dv TRUE
on success and
.Dv FALSE
on failure.
.It Fn clnt_create
Generic client creation routine for program
.Fa prognum
and version
.Fa versnum .
.Fa host
identifies the name of the remote host where the server
is located.
.Fa nettype
indicates the class of transport protocol to use.
The transports are tried in left to right order in
.Ev NETPATH
environment variable or in top to bottom order in
the netconfig database.
.Fn clnt_create
tries all the transports of the
.Fa nettype
class available from the
.Ev NETPATH
environment variable and the netconfig database,
and chooses the first successful one.
A default timeout is set and can be modified using
.Fn clnt_control .
This routine returns
.Dv NULL
if it fails.
The
.Fn clnt_pcreateerror
routine can be used to print the reason for failure.
.Pp
Note:
.Fn clnt_create
returns a valid client handle even
if the particular version number supplied to
.Fn clnt_create
is not registered with the
.Xr rpcbind 8
service.
This mismatch will be discovered by a
.Fn clnt_call
later (see
.Xr rpc_clnt_calls 3 ) .
.It Fn clnt_create_vers
Generic client creation routine which is similar to
.Fn clnt_create
but which also checks for the
version availability.
.Fa host
identifies the name of the remote host where the server
is located.
.Fa nettype
indicates the class transport protocols to be used.
If the routine is successful it returns a client handle created for
the highest version between
.Fa vers_low
and
.Fa vers_high
that is supported by the server.
.Fa vers_outp
is set to this value.
That is, after a successful return
.Fa vers_low
<=
.Fa *vers_outp
<=
.Fa vers_high .
If no version between
.Fa vers_low
and
.Fa vers_high
is supported by the server then the routine fails and returns
.Dv NULL .
A default timeout is set and can be modified using
.Fn clnt_control .
This routine returns
.Dv NULL
if it fails.
The
.Fn clnt_pcreateerror
routine can be used to print the reason for failure.
Note:
.Fn clnt_create
returns a valid client handle even
if the particular version number supplied to
.Fn clnt_create
is not registered with the
.Xr rpcbind 8
service.
This mismatch will be discovered by a
.Fn clnt_call
later (see
.Xr rpc_clnt_calls 3 ) .
However,
.Fn clnt_create_vers
does this for you and returns a valid handle
only if a version within
the range supplied is supported by the server.
.It Fn clnt_destroy
A function macro that destroys the client's RPC handle.
Destruction usually involves deallocation
of private data structures, including
.Fa clnt
itself.
Use of
.Fa clnt
is undefined after calling
.Fn clnt_destroy .
If the RPC library opened the associated file descriptor, or
.Dv CLSET_FD_CLOSE
was set using
.Fn clnt_control ,
the file descriptor will be closed.
The caller should call
.Fn auth_destroy "clnt->cl_auth"
(before calling
.Fn clnt_destroy )
to destroy the associated
.Vt AUTH
structure (see
.Xr rpc_clnt_auth 3 ) .
.It Fn clnt_dg_create
This routine creates an RPC client for the remote program
.Fa prognum
and version
.Fa versnum ;
the client uses a connectionless transport.
The remote program is located at address
.Fa svcaddr .
The parameter
.Fa fildes
is an open and bound file descriptor.
This routine will resend the call message in intervals of
15 seconds until a response is received or until the
call times out.
The total time for the call to time out is specified by
.Fn clnt_call
(see
.Fn clnt_call
in
.Xr rpc_clnt_calls 3 ) .
The retry time out and the total time out periods can
be changed using
.Fn clnt_control .
The user may set the size of the send and receive
buffers with the parameters
.Fa sendsz
and
.Fa recvsz ;
values of 0 choose suitable defaults.
This routine returns
.Dv NULL
if it fails.
.It Fn clnt_pcreateerror
Print a message to standard error indicating
why a client RPC handle could not be created.
The message is prepended with the string
.Fa s
and a colon, and appended with a newline.
.It Fn clnt_spcreateerror
Like
.Fn clnt_pcreateerror ,
except that it returns a string
instead of printing to the standard error.
A newline is not appended to the message in this case.
Warning:
returns a pointer to a buffer that is overwritten
on each call.
.It Fn clnt_raw_create
This routine creates an RPC
client handle for the remote program
.Fa prognum
and version
.Fa versnum .
The transport used to pass messages to the service is
a buffer within the process's address space,
so the corresponding RPC
server should live in the same address space;
(see
.Fn svc_raw_create
in
.Xr rpc_svc_create 3 ) .
This allows simulation of RPC and measurement of
RPC overheads, such as round trip times,
without any kernel or networking interference.
This routine returns
.Dv NULL
if it fails.
.Fn clnt_raw_create
should be called after
.Fn svc_raw_create .
.It Fn clnt_tli_create
This routine creates an RPC
client handle for the remote program
.Fa prognum
and version
.Fa versnum .
The remote program is located at address
.Fa svcaddr .
If
.Fa svcaddr
is
.Dv NULL
and it is connection-oriented, it is assumed that the file descriptor
is connected.
For connectionless transports, if
.Fa svcaddr
is
.Dv NULL ,
.Dv RPC_UNKNOWNADDR
error is set.
.Fa fildes
is a file descriptor which may be open, bound and connected.
If it is
.Dv RPC_ANYFD ,
it opens a file descriptor on the transport specified by
.Fa netconf .
If
.Fa fildes
is
.Dv RPC_ANYFD
and
.Fa netconf
is
.Dv NULL ,
a
.Dv RPC_UNKNOWNPROTO
error is set.
If
.Fa fildes
is unbound, then it will attempt to bind the descriptor.
The user may specify the size of the buffers with the parameters
.Fa sendsz
and
.Fa recvsz ;
values of 0 choose suitable defaults.
Depending upon the type of the transport (connection-oriented
or connectionless),
.Fn clnt_tli_create
calls appropriate client creation routines.
This routine returns
.Dv NULL
if it fails.
The
.Fn clnt_pcreateerror
routine can be used to print the reason for failure.
The remote rpcbind
service (see
.Xr rpcbind 8 )
is not consulted for the address of the remote
service.
.It Fn clnt_tp_create
Like
.Fn clnt_create
except
.Fn clnt_tp_create
tries only one transport specified through
.Fa netconf .
.Fn clnt_tp_create
creates a client handle for the program
.Fa prognum ,
the version
.Fa versnum ,
and for the transport specified by
.Fa netconf .
Default options are set,
which can be changed using
.Fn clnt_control
calls.
The remote rpcbind service on the host
.Fa host
is consulted for the address of the remote service.
This routine returns
.Dv NULL
if it fails.
The
.Fn clnt_pcreateerror
routine can be used to print the reason for failure.
.It Fn clnt_vc_create
This routine creates an RPC
client for the remote program
.Fa prognum
and version
.Fa versnum ;
the client uses a connection-oriented transport.
The remote program is located at address
.Fa svcaddr .
The parameter
.Fa fildes
is an open and bound file descriptor.
The user may specify the size of the send and receive buffers
with the parameters
.Fa sendsz
and
.Fa recvsz ;
values of 0 choose suitable defaults.
This routine returns
.Dv NULL
if it fails.
The address
.Fa svcaddr
should not be
.Dv NULL
and should point to the actual address of the remote program.
.Fn clnt_vc_create
does not consult the remote rpcbind service for this information.
.It Xo
.Vt "struct rpc_createerr" Va rpc_createerr ;
.Xc
A global variable whose value is set by any RPC
client handle creation routine
that fails.
It is used by the routine
.Fn clnt_pcreateerror
to print the reason for the failure.
.El
.Sh SEE ALSO
.Xr rpc 3 ,
.Xr rpc_clnt_auth 3 ,
.Xr rpc_clnt_calls 3 ,
.Xr rpcbind 8

85
lib/libc/rpc/rpc_com.h Normal file
View File

@ -0,0 +1,85 @@
/* $NetBSD: rpc_com.h,v 1.3 2000/12/10 04:10:08 christos Exp $ */
/* $FreeBSD$ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
*/
/*
* rpc_com.h, Common definitions for both the server and client side.
* All for the topmost layer of rpc
*
* In Sun's tirpc distribution, this was installed as <rpc/rpc_com.h>,
* but as it contains only non-exported interfaces, it was moved here.
*/
#ifndef _RPC_RPCCOM_H
#define _RPC_RPCCOM_H
#include <sys/cdefs.h>
/* #pragma ident "@(#)rpc_com.h 1.11 93/07/05 SMI" */
/*
* The max size of the transport, if the size cannot be determined
* by other means.
*/
#define RPC_MAXDATASIZE 9000
#define RPC_MAXADDRSIZE 1024
#define __RPC_GETXID(now) ((u_int32_t)getpid() ^ (u_int32_t)(now)->tv_sec ^ \
(u_int32_t)(now)->tv_usec)
__BEGIN_DECLS
extern u_int __rpc_get_a_size __P((int));
extern int __rpc_dtbsize __P((void));
extern struct netconfig * __rpcgettp __P((int));
extern int __rpc_get_default_domain __P((char **));
char *__rpc_taddr2uaddr_af __P((int, const struct netbuf *));
struct netbuf *__rpc_uaddr2taddr_af __P((int, const char *));
int __rpc_fixup_addr __P((struct netbuf *, const struct netbuf *));
int __rpc_sockinfo2netid __P((struct __rpc_sockinfo *, const char **));
int __rpc_seman2socktype __P((int));
int __rpc_socktype2seman __P((int));
void *rpc_nullproc __P((CLIENT *));
int __rpc_sockisbound __P((int));
struct netbuf *__rpcb_findaddr __P((rpcprog_t, rpcvers_t,
const struct netconfig *,
const char *, CLIENT **));
bool_t __rpc_control __P((int,void *));
char *_get_next_token __P((char *, int));
__END_DECLS
#endif /* _RPC_RPCCOM_H */

View File

@ -1,3 +1,5 @@
/* $NetBSD: rpc_commondata.c,v 1.7 2000/06/02 23:11:13 fvdl Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -5,39 +7,42 @@
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)rpc_commondata.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *sccsid = "@(#)rpc_commondata.c 2.1 88/07/29 4.0 RPCSRC";
static char *rcsid = "$FreeBSD$";
#endif
#include "namespace.h"
#include <rpc/rpc.h>
#include "un-namespace.h"
/*
* This file should only contain common data (global data) that is exported
* by public interfaces
* by public interfaces
*/
struct opaque_auth _null_auth;
fd_set svc_fdset;
int svc_maxfd = -1;
struct rpc_createerr rpc_createerr;

View File

@ -1,3 +1,5 @@
/* $NetBSD: rpc_dtablesize.c,v 1.14 1998/11/15 17:32:43 christos Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -27,14 +29,18 @@
* Mountain View, California 94043
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)rpc_dtablesize.c 1.2 87/08/11 Copyr 1987 Sun Micro";*/
/*static char *sccsid = "from: @(#)rpc_dtablesize.c 2.1 88/07/29 4.0 RPCSRC";*/
static char *rcsid = "$FreeBSD$";
#endif
#include <sys/types.h>
#include "namespace.h"
#include <unistd.h>
#include "un-namespace.h"
int _rpc_dtablesize __P((void)); /* XXX */
/*
* Cache the result of getdtablesize(), so we don't have to do an

816
lib/libc/rpc/rpc_generic.c Normal file
View File

@ -0,0 +1,816 @@
/* $NetBSD: rpc_generic.c,v 1.4 2000/09/28 09:07:04 kleink Exp $ */
/* $FreeBSD$ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1986-1991 by Sun Microsystems Inc.
*/
/* #pragma ident "@(#)rpc_generic.c 1.17 94/04/24 SMI" */
/*
* rpc_generic.c, Miscl routines for RPC.
*
*/
#include "reentrant.h"
#include "namespace.h"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/un.h>
#include <sys/resource.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <rpc/rpc.h>
#include <ctype.h>
#include <stdio.h>
#include <netdb.h>
#include <netconfig.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <rpc/nettype.h>
#include "un-namespace.h"
#include "rpc_com.h"
struct handle {
NCONF_HANDLE *nhandle;
int nflag; /* Whether NETPATH or NETCONFIG */
int nettype;
};
static const struct _rpcnettype {
const char *name;
const int type;
} _rpctypelist[] = {
{ "netpath", _RPC_NETPATH },
{ "visible", _RPC_VISIBLE },
{ "circuit_v", _RPC_CIRCUIT_V },
{ "datagram_v", _RPC_DATAGRAM_V },
{ "circuit_n", _RPC_CIRCUIT_N },
{ "datagram_n", _RPC_DATAGRAM_N },
{ "tcp", _RPC_TCP },
{ "udp", _RPC_UDP },
{ 0, _RPC_NONE }
};
struct netid_af {
const char *netid;
int af;
int protocol;
};
static const struct netid_af na_cvt[] = {
{ "udp", AF_INET, IPPROTO_UDP },
{ "tcp", AF_INET, IPPROTO_TCP },
#ifdef INET6
{ "udp6", AF_INET6, IPPROTO_UDP },
{ "tcp6", AF_INET6, IPPROTO_TCP },
#endif
{ "unix", AF_LOCAL, 0 }
};
#if 0
static char *strlocase __P((char *));
#endif
static int getnettype __P((const char *));
/*
* Cache the result of getrlimit(), so we don't have to do an
* expensive call every time.
*/
int
__rpc_dtbsize()
{
static int tbsize;
struct rlimit rl;
if (tbsize) {
return (tbsize);
}
if (getrlimit(RLIMIT_NOFILE, &rl) == 0) {
return (tbsize = (int)rl.rlim_max);
}
/*
* Something wrong. I'll try to save face by returning a
* pessimistic number.
*/
return (32);
}
/*
* Find the appropriate buffer size
*/
u_int
/*ARGSUSED*/
__rpc_get_t_size(af, proto, size)
int af, proto;
int size; /* Size requested */
{
int maxsize;
switch (proto) {
case IPPROTO_TCP:
maxsize = 65536; /* XXX */
break;
case IPPROTO_UDP:
maxsize = 8192; /* XXX */
break;
default:
maxsize = RPC_MAXDATASIZE;
break;
}
if (size == 0)
return maxsize;
/* Check whether the value is within the upper max limit */
return (size > maxsize ? (u_int)maxsize : (u_int)size);
}
/*
* Find the appropriate address buffer size
*/
u_int
__rpc_get_a_size(af)
int af;
{
switch (af) {
case AF_INET:
return sizeof (struct sockaddr_in);
#ifdef INET6
case AF_INET6:
return sizeof (struct sockaddr_in6);
#endif
case AF_LOCAL:
return sizeof (struct sockaddr_un);
default:
break;
}
return ((u_int)RPC_MAXADDRSIZE);
}
#if 0
static char *
strlocase(p)
char *p;
{
char *t = p;
for (; *p; p++)
if (isupper(*p))
*p = tolower(*p);
return (t);
}
#endif
/*
* Returns the type of the network as defined in <rpc/nettype.h>
* If nettype is NULL, it defaults to NETPATH.
*/
static int
getnettype(nettype)
const char *nettype;
{
int i;
if ((nettype == NULL) || (nettype[0] == NULL)) {
return (_RPC_NETPATH); /* Default */
}
#if 0
nettype = strlocase(nettype);
#endif
for (i = 0; _rpctypelist[i].name; i++)
if (strcasecmp(nettype, _rpctypelist[i].name) == 0) {
return (_rpctypelist[i].type);
}
return (_rpctypelist[i].type);
}
/*
* For the given nettype (tcp or udp only), return the first structure found.
* This should be freed by calling freenetconfigent()
*/
struct netconfig *
__rpc_getconfip(nettype)
const char *nettype;
{
char *netid;
char *netid_tcp = (char *) NULL;
char *netid_udp = (char *) NULL;
static char *netid_tcp_main;
static char *netid_udp_main;
struct netconfig *dummy;
int main_thread;
static thread_key_t tcp_key, udp_key;
extern mutex_t tsd_lock;
if ((main_thread = thr_main())) {
netid_udp = netid_udp_main;
netid_tcp = netid_tcp_main;
} else {
if (tcp_key == 0) {
mutex_lock(&tsd_lock);
if (tcp_key == 0)
thr_keycreate(&tcp_key, free);
mutex_unlock(&tsd_lock);
}
netid_tcp = (char *)thr_getspecific(tcp_key);
if (udp_key == 0) {
mutex_lock(&tsd_lock);
if (udp_key == 0)
thr_keycreate(&udp_key, free);
mutex_unlock(&tsd_lock);
}
netid_udp = (char *)thr_getspecific(udp_key);
}
if (!netid_udp && !netid_tcp) {
struct netconfig *nconf;
void *confighandle;
if (!(confighandle = setnetconfig())) {
syslog (LOG_ERR, "rpc: failed to open " NETCONFIG);
return (NULL);
}
while ((nconf = getnetconfig(confighandle)) != NULL) {
if (strcmp(nconf->nc_protofmly, NC_INET) == 0) {
if (strcmp(nconf->nc_proto, NC_TCP) == 0) {
netid_tcp = strdup(nconf->nc_netid);
if (main_thread)
netid_tcp_main = netid_tcp;
else
thr_setspecific(tcp_key,
(void *) netid_tcp);
} else
if (strcmp(nconf->nc_proto, NC_UDP) == 0) {
netid_udp = strdup(nconf->nc_netid);
if (main_thread)
netid_udp_main = netid_udp;
else
thr_setspecific(udp_key,
(void *) netid_udp);
}
}
}
endnetconfig(confighandle);
}
if (strcmp(nettype, "udp") == 0)
netid = netid_udp;
else if (strcmp(nettype, "tcp") == 0)
netid = netid_tcp;
else {
return (NULL);
}
if ((netid == NULL) || (netid[0] == NULL)) {
return (NULL);
}
dummy = getnetconfigent(netid);
return (dummy);
}
/*
* Returns the type of the nettype, which should then be used with
* __rpc_getconf().
*/
void *
__rpc_setconf(nettype)
const char *nettype;
{
struct handle *handle;
handle = (struct handle *) malloc(sizeof (struct handle));
if (handle == NULL) {
return (NULL);
}
switch (handle->nettype = getnettype(nettype)) {
case _RPC_NETPATH:
case _RPC_CIRCUIT_N:
case _RPC_DATAGRAM_N:
if (!(handle->nhandle = setnetpath())) {
free(handle);
return (NULL);
}
handle->nflag = TRUE;
break;
case _RPC_VISIBLE:
case _RPC_CIRCUIT_V:
case _RPC_DATAGRAM_V:
case _RPC_TCP:
case _RPC_UDP:
if (!(handle->nhandle = setnetconfig())) {
syslog (LOG_ERR, "rpc: failed to open " NETCONFIG);
free(handle);
return (NULL);
}
handle->nflag = FALSE;
break;
default:
return (NULL);
}
return (handle);
}
/*
* Returns the next netconfig struct for the given "net" type.
* __rpc_setconf() should have been called previously.
*/
struct netconfig *
__rpc_getconf(vhandle)
void *vhandle;
{
struct handle *handle;
struct netconfig *nconf;
handle = (struct handle *)vhandle;
if (handle == NULL) {
return (NULL);
}
for (;;) {
if (handle->nflag)
nconf = getnetpath(handle->nhandle);
else
nconf = getnetconfig(handle->nhandle);
if (nconf == NULL)
break;
if ((nconf->nc_semantics != NC_TPI_CLTS) &&
(nconf->nc_semantics != NC_TPI_COTS) &&
(nconf->nc_semantics != NC_TPI_COTS_ORD))
continue;
switch (handle->nettype) {
case _RPC_VISIBLE:
if (!(nconf->nc_flag & NC_VISIBLE))
continue;
/* FALLTHROUGH */
case _RPC_NETPATH: /* Be happy */
break;
case _RPC_CIRCUIT_V:
if (!(nconf->nc_flag & NC_VISIBLE))
continue;
/* FALLTHROUGH */
case _RPC_CIRCUIT_N:
if ((nconf->nc_semantics != NC_TPI_COTS) &&
(nconf->nc_semantics != NC_TPI_COTS_ORD))
continue;
break;
case _RPC_DATAGRAM_V:
if (!(nconf->nc_flag & NC_VISIBLE))
continue;
/* FALLTHROUGH */
case _RPC_DATAGRAM_N:
if (nconf->nc_semantics != NC_TPI_CLTS)
continue;
break;
case _RPC_TCP:
if (((nconf->nc_semantics != NC_TPI_COTS) &&
(nconf->nc_semantics != NC_TPI_COTS_ORD)) ||
(strcmp(nconf->nc_protofmly, NC_INET)
#ifdef INET6
&& strcmp(nconf->nc_protofmly, NC_INET6))
#else
)
#endif
||
strcmp(nconf->nc_proto, NC_TCP))
continue;
break;
case _RPC_UDP:
if ((nconf->nc_semantics != NC_TPI_CLTS) ||
(strcmp(nconf->nc_protofmly, NC_INET)
#ifdef INET6
&& strcmp(nconf->nc_protofmly, NC_INET6))
#else
)
#endif
||
strcmp(nconf->nc_proto, NC_UDP))
continue;
break;
}
break;
}
return (nconf);
}
void
__rpc_endconf(vhandle)
void * vhandle;
{
struct handle *handle;
handle = (struct handle *) vhandle;
if (handle == NULL) {
return;
}
if (handle->nflag) {
endnetpath(handle->nhandle);
} else {
endnetconfig(handle->nhandle);
}
free(handle);
}
/*
* Used to ping the NULL procedure for clnt handle.
* Returns NULL if fails, else a non-NULL pointer.
*/
void *
rpc_nullproc(clnt)
CLIENT *clnt;
{
struct timeval TIMEOUT = {25, 0};
if (clnt_call(clnt, NULLPROC, (xdrproc_t) xdr_void, NULL,
(xdrproc_t) xdr_void, NULL, TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return ((void *) clnt);
}
/*
* Try all possible transports until
* one succeeds in finding the netconf for the given fd.
*/
struct netconfig *
__rpcgettp(fd)
int fd;
{
const char *netid;
struct __rpc_sockinfo si;
if (!__rpc_fd2sockinfo(fd, &si))
return NULL;
if (!__rpc_sockinfo2netid(&si, &netid))
return NULL;
/*LINTED const castaway*/
return getnetconfigent((char *)netid);
}
int
__rpc_fd2sockinfo(int fd, struct __rpc_sockinfo *sip)
{
socklen_t len;
int type, proto;
struct sockaddr_storage ss;
len = sizeof ss;
if (_getsockname(fd, (struct sockaddr *)(void *)&ss, &len) < 0)
return 0;
sip->si_alen = len;
len = sizeof type;
if (_getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &len) < 0)
return 0;
/* XXX */
if (ss.ss_family != AF_LOCAL) {
if (type == SOCK_STREAM)
proto = IPPROTO_TCP;
else if (type == SOCK_DGRAM)
proto = IPPROTO_UDP;
else
return 0;
} else
proto = 0;
sip->si_af = ss.ss_family;
sip->si_proto = proto;
sip->si_socktype = type;
return 1;
}
/*
* Linear search, but the number of entries is small.
*/
int
__rpc_nconf2sockinfo(const struct netconfig *nconf, struct __rpc_sockinfo *sip)
{
int i;
for (i = 0; i < (sizeof na_cvt) / (sizeof (struct netid_af)); i++)
if (!strcmp(na_cvt[i].netid, nconf->nc_netid)) {
sip->si_af = na_cvt[i].af;
sip->si_proto = na_cvt[i].protocol;
sip->si_socktype =
__rpc_seman2socktype((int)nconf->nc_semantics);
if (sip->si_socktype == -1)
return 0;
sip->si_alen = __rpc_get_a_size(sip->si_af);
return 1;
}
return 0;
}
int
__rpc_nconf2fd(const struct netconfig *nconf)
{
struct __rpc_sockinfo si;
if (!__rpc_nconf2sockinfo(nconf, &si))
return 0;
return _socket(si.si_af, si.si_socktype, si.si_proto);
}
int
__rpc_sockinfo2netid(struct __rpc_sockinfo *sip, const char **netid)
{
int i;
for (i = 0; i < (sizeof na_cvt) / (sizeof (struct netid_af)); i++)
if (na_cvt[i].af == sip->si_af &&
na_cvt[i].protocol == sip->si_proto) {
if (netid)
*netid = na_cvt[i].netid;
return 1;
}
return 0;
}
char *
taddr2uaddr(const struct netconfig *nconf, const struct netbuf *nbuf)
{
struct __rpc_sockinfo si;
if (!__rpc_nconf2sockinfo(nconf, &si))
return NULL;
return __rpc_taddr2uaddr_af(si.si_af, nbuf);
}
struct netbuf *
uaddr2taddr(const struct netconfig *nconf, const char *uaddr)
{
struct __rpc_sockinfo si;
if (!__rpc_nconf2sockinfo(nconf, &si))
return NULL;
return __rpc_uaddr2taddr_af(si.si_af, uaddr);
}
char *
__rpc_taddr2uaddr_af(int af, const struct netbuf *nbuf)
{
char *ret;
struct sockaddr_in *sin;
struct sockaddr_un *sun;
char namebuf[INET_ADDRSTRLEN];
#ifdef INET6
struct sockaddr_in6 *sin6;
char namebuf6[INET6_ADDRSTRLEN];
#endif
u_int16_t port;
switch (af) {
case AF_INET:
sin = nbuf->buf;
if (inet_ntop(af, &sin->sin_addr, namebuf, sizeof namebuf)
== NULL)
return NULL;
port = ntohs(sin->sin_port);
if (asprintf(&ret, "%s.%u.%u", namebuf, ((u_int32_t)port) >> 8,
port & 0xff) < 0)
return NULL;
break;
#ifdef INET6
case AF_INET6:
sin6 = nbuf->buf;
if (inet_ntop(af, &sin6->sin6_addr, namebuf6, sizeof namebuf6)
== NULL)
return NULL;
port = ntohs(sin6->sin6_port);
if (asprintf(&ret, "%s.%u.%u", namebuf6, ((u_int32_t)port) >> 8,
port & 0xff) < 0)
return NULL;
break;
#endif
case AF_LOCAL:
sun = nbuf->buf;
sun->sun_path[sizeof(sun->sun_path) - 1] = '\0'; /* safety */
ret = strdup(sun->sun_path);
break;
default:
return NULL;
}
return ret;
}
struct netbuf *
__rpc_uaddr2taddr_af(int af, const char *uaddr)
{
struct netbuf *ret = NULL;
char *addrstr, *p;
unsigned port, portlo, porthi;
struct sockaddr_in *sin;
#ifdef INET6
struct sockaddr_in6 *sin6;
#endif
struct sockaddr_un *sun;
addrstr = strdup(uaddr);
if (addrstr == NULL)
return NULL;
/*
* AF_LOCAL addresses are expected to be absolute
* pathnames, anything else will be AF_INET or AF_INET6.
*/
if (*addrstr != '/') {
p = strrchr(addrstr, '.');
if (p == NULL)
goto out;
portlo = (unsigned)atoi(p + 1);
*p = '\0';
p = strrchr(addrstr, '.');
if (p == NULL)
goto out;
porthi = (unsigned)atoi(p + 1);
*p = '\0';
port = (porthi << 8) | portlo;
}
ret = (struct netbuf *)malloc(sizeof *ret);
switch (af) {
case AF_INET:
sin = (struct sockaddr_in *)malloc(sizeof *sin);
if (sin == NULL)
goto out;
memset(sin, 0, sizeof *sin);
sin->sin_family = AF_INET;
sin->sin_port = htons(port);
if (inet_pton(AF_INET, addrstr, &sin->sin_addr) <= 0) {
free(sin);
free(ret);
ret = NULL;
goto out;
}
sin->sin_len = ret->maxlen = ret->len = sizeof *sin;
ret->buf = sin;
break;
#ifdef INET6
case AF_INET6:
sin6 = (struct sockaddr_in6 *)malloc(sizeof *sin6);
if (sin6 == NULL)
goto out;
memset(sin6, 0, sizeof *sin6);
sin6->sin6_family = AF_INET6;
sin6->sin6_port = htons(port);
if (inet_pton(AF_INET6, addrstr, &sin6->sin6_addr) <= 0) {
free(sin);
free(ret);
ret = NULL;
goto out;
}
sin6->sin6_len = ret->maxlen = ret->len = sizeof *sin6;
ret->buf = sin6;
break;
#endif
case AF_LOCAL:
sun = (struct sockaddr_un *)malloc(sizeof *sun);
if (sun == NULL)
goto out;
memset(sun, 0, sizeof *sun);
sun->sun_family = AF_LOCAL;
strncpy(sun->sun_path, addrstr, sizeof(sun->sun_path) - 1);
break;
default:
break;
}
out:
free(addrstr);
return ret;
}
int
__rpc_seman2socktype(int semantics)
{
switch (semantics) {
case NC_TPI_CLTS:
return SOCK_DGRAM;
case NC_TPI_COTS_ORD:
return SOCK_STREAM;
case NC_TPI_RAW:
return SOCK_RAW;
default:
break;
}
return -1;
}
int
__rpc_socktype2seman(int socktype)
{
switch (socktype) {
case SOCK_DGRAM:
return NC_TPI_CLTS;
case SOCK_STREAM:
return NC_TPI_COTS_ORD;
case SOCK_RAW:
return NC_TPI_RAW;
default:
break;
}
return -1;
}
/*
* XXXX - IPv6 scope IDs can't be handled in universal addresses.
* Here, we compare the original server address to that of the RPC
* service we just received back from a call to rpcbind on the remote
* machine. If they are both "link local" or "site local", copy
* the scope id of the server address over to the service address.
*/
int
__rpc_fixup_addr(struct netbuf *new, const struct netbuf *svc)
{
#ifdef INET6
struct sockaddr *sa_new, *sa_svc;
struct sockaddr_in6 *sin6_new, *sin6_svc;
sa_svc = (struct sockaddr *)svc->buf;
sa_new = (struct sockaddr *)new->buf;
if (sa_new->sa_family == sa_svc->sa_family &&
sa_new->sa_family == AF_INET6) {
sin6_new = (struct sockaddr_in6 *)new->buf;
sin6_svc = (struct sockaddr_in6 *)svc->buf;
if ((IN6_IS_ADDR_LINKLOCAL(&sin6_new->sin6_addr) &&
IN6_IS_ADDR_LINKLOCAL(&sin6_svc->sin6_addr)) ||
(IN6_IS_ADDR_SITELOCAL(&sin6_new->sin6_addr) &&
IN6_IS_ADDR_SITELOCAL(&sin6_svc->sin6_addr))) {
sin6_new->sin6_scope_id = sin6_svc->sin6_scope_id;
}
}
#endif
return 1;
}
int
__rpc_sockisbound(int fd)
{
struct sockaddr_storage ss;
socklen_t slen;
slen = sizeof (struct sockaddr_storage);
if (_getsockname(fd, (struct sockaddr *)(void *)&ss, &slen) < 0)
return 0;
switch (ss.ss_family) {
case AF_INET:
return (((struct sockaddr_in *)
(void *)&ss)->sin_port != 0);
#ifdef INET6
case AF_INET6:
return (((struct sockaddr_in6 *)
(void *)&ss)->sin6_port != 0);
#endif
case AF_LOCAL:
/* XXX check this */
return (((struct sockaddr_un *)
(void *)&ss)->sun_path[0] != '\0');
default:
break;
}
return 0;
}

View File

@ -1,3 +1,5 @@
/* $NetBSD: rpc_prot.c,v 1.16 2000/06/02 23:11:13 fvdl Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@ -27,9 +29,10 @@
* Mountain View, California 94043
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)rpc_prot.c 2.3 88/08/07 4.0 RPCSRC";*/
static char *sccsid = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";
static char *sccsid = "@(#)rpc_prot.c 2.3 88/08/07 4.0 RPCSRC";
static char *rcsid = "$FreeBSD$";
#endif
@ -46,13 +49,20 @@ static char *rcsid = "$FreeBSD$";
* routines are also in this program.
*/
#include "namespace.h"
#include <sys/param.h>
#include <assert.h>
#include <rpc/rpc.h>
#include "un-namespace.h"
static void accepted __P((enum accept_stat, struct rpc_err *));
static void rejected __P((enum reject_stat, struct rpc_err *));
/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
struct opaque_auth _null_auth;
extern struct opaque_auth _null_auth;
/*
* XDR an opaque authentication struct
@ -60,10 +70,13 @@ struct opaque_auth _null_auth;
*/
bool_t
xdr_opaque_auth(xdrs, ap)
register XDR *xdrs;
register struct opaque_auth *ap;
XDR *xdrs;
struct opaque_auth *ap;
{
assert(xdrs != NULL);
assert(ap != NULL);
if (xdr_enum(xdrs, &(ap->oa_flavor)))
return (xdr_bytes(xdrs, &ap->oa_base,
&ap->oa_length, MAX_AUTH_BYTES));
@ -75,10 +88,14 @@ xdr_opaque_auth(xdrs, ap)
*/
bool_t
xdr_des_block(xdrs, blkp)
register XDR *xdrs;
register des_block *blkp;
XDR *xdrs;
des_block *blkp;
{
return (xdr_opaque(xdrs, (caddr_t)blkp, sizeof(des_block)));
assert(xdrs != NULL);
assert(blkp != NULL);
return (xdr_opaque(xdrs, (caddr_t)(void *)blkp, sizeof(des_block)));
}
/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
@ -88,10 +105,13 @@ xdr_des_block(xdrs, blkp)
*/
bool_t
xdr_accepted_reply(xdrs, ar)
register XDR *xdrs;
register struct accepted_reply *ar;
XDR *xdrs;
struct accepted_reply *ar;
{
assert(xdrs != NULL);
assert(ar != NULL);
/* personalized union, rather than calling xdr_union */
if (! xdr_opaque_auth(xdrs, &(ar->ar_verf)))
return (FALSE);
@ -106,7 +126,11 @@ xdr_accepted_reply(xdrs, ar)
if (! xdr_u_int32_t(xdrs, &(ar->ar_vers.low)))
return (FALSE);
return (xdr_u_int32_t(xdrs, &(ar->ar_vers.high)));
default:
case GARBAGE_ARGS:
case SYSTEM_ERR:
case PROC_UNAVAIL:
case PROG_UNAVAIL:
break;
}
return (TRUE); /* TRUE => open ended set of problems */
@ -115,12 +139,15 @@ xdr_accepted_reply(xdrs, ar)
/*
* XDR the MSG_DENIED part of a reply message union
*/
bool_t
bool_t
xdr_rejected_reply(xdrs, rr)
register XDR *xdrs;
register struct rejected_reply *rr;
XDR *xdrs;
struct rejected_reply *rr;
{
assert(xdrs != NULL);
assert(rr != NULL);
/* personalized union, rather than calling xdr_union */
if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat)))
return (FALSE);
@ -134,12 +161,14 @@ xdr_rejected_reply(xdrs, rr)
case AUTH_ERROR:
return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why)));
}
/* NOTREACHED */
assert(0);
return (FALSE);
}
static struct xdr_discrim reply_dscrm[3] = {
{ (int)MSG_ACCEPTED, xdr_accepted_reply },
{ (int)MSG_DENIED, xdr_rejected_reply },
static const struct xdr_discrim reply_dscrm[3] = {
{ (int)MSG_ACCEPTED, (xdrproc_t)xdr_accepted_reply },
{ (int)MSG_DENIED, (xdrproc_t)xdr_rejected_reply },
{ __dontcare__, NULL_xdrproc_t } };
/*
@ -147,15 +176,19 @@ static struct xdr_discrim reply_dscrm[3] = {
*/
bool_t
xdr_replymsg(xdrs, rmsg)
register XDR *xdrs;
register struct rpc_msg *rmsg;
XDR *xdrs;
struct rpc_msg *rmsg;
{
assert(xdrs != NULL);
assert(rmsg != NULL);
if (
xdr_u_int32_t(xdrs, &(rmsg->rm_xid)) &&
xdr_u_int32_t(xdrs, &(rmsg->rm_xid)) &&
xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) &&
(rmsg->rm_direction == REPLY) )
return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
(caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t));
(caddr_t)(void *)&(rmsg->rm_reply.ru), reply_dscrm,
NULL_xdrproc_t));
return (FALSE);
}
@ -167,10 +200,13 @@ xdr_replymsg(xdrs, rmsg)
*/
bool_t
xdr_callhdr(xdrs, cmsg)
register XDR *xdrs;
register struct rpc_msg *cmsg;
XDR *xdrs;
struct rpc_msg *cmsg;
{
assert(xdrs != NULL);
assert(cmsg != NULL);
cmsg->rm_direction = CALL;
cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
if (
@ -179,7 +215,7 @@ xdr_callhdr(xdrs, cmsg)
xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_prog)) )
return (xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers)));
return (xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers)));
return (FALSE);
}
@ -187,10 +223,12 @@ xdr_callhdr(xdrs, cmsg)
static void
accepted(acpt_stat, error)
register enum accept_stat acpt_stat;
register struct rpc_err *error;
enum accept_stat acpt_stat;
struct rpc_err *error;
{
assert(error != NULL);
switch (acpt_stat) {
case PROG_UNAVAIL:
@ -217,34 +255,35 @@ accepted(acpt_stat, error)
error->re_status = RPC_SUCCESS;
return;
}
/* NOTREACHED */
/* something's wrong, but we don't know what ... */
error->re_status = RPC_FAILED;
error->re_lb.s1 = (long)MSG_ACCEPTED;
error->re_lb.s2 = (long)acpt_stat;
error->re_lb.s1 = (int32_t)MSG_ACCEPTED;
error->re_lb.s2 = (int32_t)acpt_stat;
}
static void
static void
rejected(rjct_stat, error)
register enum reject_stat rjct_stat;
register struct rpc_err *error;
enum reject_stat rjct_stat;
struct rpc_err *error;
{
switch (rjct_stat) {
assert(error != NULL);
case RPC_VERSMISMATCH:
switch (rjct_stat) {
case RPC_MISMATCH:
error->re_status = RPC_VERSMISMATCH;
return;
case AUTH_ERROR:
error->re_status = RPC_AUTHERROR;
return;
default:
break;
}
/* something's wrong, but we don't know what ... */
/* NOTREACHED */
error->re_status = RPC_FAILED;
error->re_lb.s1 = (long)MSG_DENIED;
error->re_lb.s2 = (long)rjct_stat;
error->re_lb.s1 = (int32_t)MSG_DENIED;
error->re_lb.s2 = (int32_t)rjct_stat;
}
/*
@ -252,10 +291,13 @@ rejected(rjct_stat, error)
*/
void
_seterr_reply(msg, error)
register struct rpc_msg *msg;
register struct rpc_err *error;
struct rpc_msg *msg;
struct rpc_err *error;
{
assert(msg != NULL);
assert(error != NULL);
/* optimized for normal, SUCCESSful case */
switch (msg->rm_reply.rp_stat) {
@ -263,7 +305,7 @@ _seterr_reply(msg, error)
if (msg->acpted_rply.ar_stat == SUCCESS) {
error->re_status = RPC_SUCCESS;
return;
};
}
accepted(msg->acpted_rply.ar_stat, error);
break;
@ -273,7 +315,7 @@ _seterr_reply(msg, error)
default:
error->re_status = RPC_FAILED;
error->re_lb.s1 = (long)(msg->rm_reply.rp_stat);
error->re_lb.s1 = (int32_t)(msg->rm_reply.rp_stat);
break;
}
switch (error->re_status) {
@ -291,6 +333,22 @@ _seterr_reply(msg, error)
error->re_vers.low = msg->acpted_rply.ar_vers.low;
error->re_vers.high = msg->acpted_rply.ar_vers.high;
break;
case RPC_FAILED:
case RPC_SUCCESS:
case RPC_PROGNOTREGISTERED:
case RPC_PMAPFAILURE:
case RPC_UNKNOWNPROTO:
case RPC_UNKNOWNHOST:
case RPC_SYSTEMERROR:
case RPC_CANTDECODEARGS:
case RPC_PROCUNAVAIL:
case RPC_PROGUNAVAIL:
case RPC_TIMEDOUT:
case RPC_CANTRECV:
case RPC_CANTSEND:
case RPC_CANTDECODERES:
case RPC_CANTENCODEARGS:
default:
break;
}

Some files were not shown because too many files have changed in this diff Show More