BEGIN
{
use
vars
qw(@ISA @EXPORT_OK %EXPORT_TAGS)
;
@ISA
=
qw(Exporter)
;
$EXPORT_TAGS
{packet} = [
qw(&call_packet &reply_packet &packet)
];
$EXPORT_TAGS
{simple} = [
qw(&opaque &unsigned &void)
];
$EXPORT_TAGS
{all} = [@{
$EXPORT_TAGS
{packet}}, @{
$EXPORT_TAGS
{simple}},
'&record'
,
'&opaque_auth'
];
Exporter::export_ok_tags (
'all'
);
}
use
XDR
qw(:msg_type :auth_flavor RPCVERS AUTH_NULL MSG_ACCEPTED)
;
my
$global_xid
= 0;
sub
packet
{
my
(
$msg_type
,
$contents
,
$xid
) =
@_
;
$xid
=
$global_xid
++
if
(!
defined
$xid
);
return
unsigned (
$xid
) . unsigned (
$msg_type
) .
$contents
;
}
sub
record
{
my
(
$data
) =
@_
;
my
(
$len
) =
length
(
$data
) | (1 << 31);
return
unsigned (
$len
) .
$data
;
}
sub
unsigned
{
my
(
$data
) =
@_
;
confess
"Non-numeric data for pack"
if
(
$data
!~ /^\d+$/);
pack
(
'N'
,
$data
);
}
sub
opaque_auth
{
my
(
$flavor
,
$body
) =
@_
;
$body
=
''
if
(!
defined
$body
);
unsigned (
$flavor
) . opaque (
$body
);
}
sub
opaque
{
my
(
$data
) =
@_
;
my
(
$len
) =
length
(
$data
);
my
$dribble
=
$len
& 3;
if
(
$dribble
)
{
$data
.=
"\0"
x (4 -
$dribble
);
}
return
unsigned (
$len
) .
$data
;
}
sub
void
{
return
''
;
}
sub
call_packet
{
my
(
$xid
,
$proc
,
$args
,
$vers
,
$prog
,
$rpcvers
) =
@_
;
$rpcvers
= RPCVERS
if
(!
defined
$rpcvers
);
return
packet (CALL,
unsigned (
$rpcvers
) .
unsigned (
$prog
) .
unsigned (
$vers
) .
unsigned (
$proc
) .
opaque_auth (AUTH_NULL) .
opaque_auth (AUTH_NULL) .
$args
,
$xid
);
}
sub
reply_packet
{
my
(
$xid
,
$status
,
$reason
,
$args
) =
@_
;
my
(
$verf
);
$args
=
''
if
(!
defined
$args
);
$verf
= opaque_auth (AUTH_NULL)
if
(
$status
== MSG_ACCEPTED);
return
packet (REPLY,
$verf
.
unsigned (
$status
) .
unsigned (
$reason
) .
$args
,
$xid
);
}
1;