Protocols pfkey(7P)
NAME
pfkey - Security association database interface
SYNOPSIS
#include
#include
#include
int socket(PFKEY,SOCKRAW,PFKEYV2);
DESCRIPTION
Keying information for IPsec security services is maintained
in security association databases (SADBs). The security
associations (SAs) are used to protect both inbound and out-
bound packets.
A user process (or possibly multiple co-operating processes)
maintains SADBs by sending messages over a special kind of
socket. This is analogous to the method described in
route(7P). Only a superuser may access an SADB.
SunOS applications that use PFKEY include ipseckey(1M) and
in.iked(1M).
The operating system may spontaneously send pfkey messages
to listening processes, such as a request for a new SA for
an outbound datagram or to report the expiration of an
existing SA.
One opens the channel for passing SADB control messages by
using the socket call shown in the section above. More than
one key socket can be open per system.
Messages are formed by a small base header, followed by zero
or more extension messages, some of which require additional
data following them. The base message and all extensions
must be eight-byte aligned. An example message is the GET
message, which requires the base header, the SA extension,
and the ADRESDST extension.
Messages
Messages include:
#define SADBGETSPI /* Get a new SPI value from the system. */
SunOS 5.11 Last change: 6 May 2008 1
Protocols pfkey(7P)
#define SADBUPDATE /* Update an SA. */
#define SADBAD /* Add a fully-formed SA. */
#define SADBDELETE /* Delete an SA. */
#define SADBGET /* Get an SA */
#define SADBACQUIRE /* Kernel needs a new SA. */
#define SADBREGISTER /* Regis. to receive ACQUIRE msgs. */
#define SADBEXPIRE /* SA has expired. */
#define SADBFLUSH /* Flush all SAs. */
#define SADBDUMP /* Get all SAs. (Unreliable) */
#define SADBXPROMISC /* Listen promiscuously */
#define SADBXINVERSEACQUIRE /* Query kernel policy,
get an ACQUIRE in return. */
#define SADBXUPDATEPAIR /* Update an SA and its pair SA */
#define SADBXDELPAIR /* Delete an SA pair. */
The base message header consists of:
struct sadbmsg {
uint8t sadbmsgversion; /* Set to PFKEYV2, for compat. */
uint8t sadbmsgtype; /* Msg. type */
uint8t sadbmsgerrno; /* Why message failed */
uint8t sadbmsgsatype; /* Which security service */
uint16t sadbmsglen; /* Length in 8-byte units */
uint16t sadbmsgreserved; /* Zero out */
#define sadbxmsgdiagnostic sadbmsgreserved
/* Extended diagnostics for errors */
uint32t sadbmsgseq; /* For msg. originator */
uint32t sadbmsgpid; /* ID originator */
};
Extension types include:
#define SADBEXTSA /* SA info */
#define SADBEXTLIFETIMEHARD /* Hard lifetime */
#define SADBEXTLIFETIMESOFT /* Soft lifetime */
#define SADBEXTADRESRC /* Source address */
#define SADBEXTADRESDST /* Destination address */
#define SADBEXTADRESPROXY /* Proxy address - DEPRECATED */
#define SADBEXTKEYAUTH /* Authen. key */
#define SADBEXTKEYENCRYPT /* Encryption key */
#define SADBEXTIDENTITYSRC /* Source certif. ID */
#define SADBEXTIDENTITYDST /* Destination certif. ID */
#define SADBEXTSENSITIVITY /* Sensitivity info */
#define SADBEXTPROPOSAL /* Security proposal */
#define SADBEXTSUPORTEDAUTH /* Supported authen. algo's */
#define SADBEXTSUPORTEDENCRYPT /* Supported encryption algo's */
#define SADBEXTSPIRANGE /* Range of possible SPIs *
#define SADBXEXTEREG /* Reg. for extended ACQUIRE */
SunOS 5.11 Last change: 6 May 2008 2
Protocols pfkey(7P)
#define SADBXEXTEPROP /* Extended ACQUIRE proposals */
#define SADBXEXTKMCOKIE /* Indicates which KM derived SA. */
#define SADBXEXTADRESNATLOC /* NAT-Traversal local (my public) */
#define SADBXEXTADRESNATREM /* NAT-T remote (peer's private) */
#define SADBXEXTADRESINERSRC /* Tunnel-mode inner source */
#define SADBXEXTADRESINERDST /* Tunnel-mode inner dest */
#define SADBXEXTPAIR /* SA pair extension.
Security Association Information Extension flags:
#define SADBSAFLAGSPFS 0x1 /* Perfect forward secrecy? */
#define SADBSAFLAGSNOREPLAY 0x2 /* Replay field NOT PRESENT. */
#define SADBXSAFLAGSUSED 0x80000000 /* SA used/not used */
#define SADBXSAFLAGSUNIQUE 0x40000000 /* SA unique/reusable */
#define SADBXSAFLAGSALG1 0x20000000 /* Auth-alg specif. flag 1 */
#define SADBXSAFLAGSALG2 0x10000000 /* Auth-alg specif. flag 2 */
#define SADBXSAFLAGSEALG1 0x8000000 /* Encr-alg specif. flag 1 */
#define SADBXSAFLAGSEALG2 0x4000000 /* Encr-alg specif. flag 2 */
#define SADBXSAFLAGSKM1 0x2000000 /* Key mgmt. specif. flag 1 */
#define SADBXSAFLAGSKM2 0x1000000 /* Key mgmt. specif. flag 2 */
#define SADBXSAFLAGSKM3 0x800000 /* Key mgmt. specif. flag 3 */
#define SADBXSAFLAGSKM4 0x400000 /* Key mgmt. specif. flag 4 */
#define SADBXSAFLAGSKRES1 0x200000 /* Reserved by the kernel */
#define SADBXSAFLAGSNATLOC 0x100000 /* this has a natted srcSA */
#define SADBXSAFLAGSNATREM 0x80000 /* this has a natted dstSA */
#define SADBXSAFLAGSKRES2 0x40000 /* Reserved by the kernel */
#define SADBXSAFLAGSTUNEL 0x20000 /* tunnel mode */
#define SADBXSAFLAGSPAIRED 0x10000 /* inbound/outbound pair*/
#define SADBXSAFLAGSOUTBOUND 0x8000 /* SA direction bit */
#define SADBXSAFLAGSINBOUND 0x4000 /* SA direction bit */
Extension headers include:
Generic Extension Header
struct sadbext {
uint16t sadbextlen; /* In 64-bit words, inclusive */
uint16t sadbexttype; /* 0 is reserved */
};
Security Association Information Extension
struct sadbsa {
uint16t sadbsalen;
uint16t sadbsaexttype; /* ASOCIATION */
uint32t sadbsaspi;
uint8t sadbsareplay;
uint8t sadbsastate;
uint8t sadbsaauth;
SunOS 5.11 Last change: 6 May 2008 3
Protocols pfkey(7P)
uint8t sadbsaencrypt;
uint32t sadbsaflags;
};
Lifetime Extension
struct sadblifetime {
uint16t sadblifetimelen;
uint16t sadblifetimeexttype; /* SOFT, HARD, CURENT */
uint32t sadblifetimeallocations;
uint64t sadblifetimebytes;
uint64t sadblifetimeaddtime;
uint64t sadblifetimeusetime;
};
Address Extension
struct sadbaddress {
uint16t sadbaddresslen;
uint16t sadbaddressexttype; /* SRC, DST, NAT*, INER* */
uint8t sadbaddressproto; /* Proto for ports... */
uint8t sadbaddressprefixlen; /* Prefix length for INER*. */
uint16t sadbaddressreserved; /* Padding */
/* Followed by a sockaddr
structure.*/
};
Keying Material Extension
struct sadbkey {
uint16t sadbkeylen;
uint16t sadbkeyexttype; /* AUTH, ENCRYPT */
uint16t sadbkeybits;
uint16t sadbkeyreserved;
/* Followed by actual key(s) in
canonical (outbound proc.) order. */
};
Indentity Extension
struct sadbident {
uint16t sadbidentlen;
uint16t sadbidentexttype; /* SRC, DST, PROXY */
uint16t sadbidenttype; /* FQDN, USERFQDN, etc. */
uint16t sadbidentreserved; /* Padding */
uint64t sadbidentid; /* For userid, etc. */
/* Followed by an identity null-terminate C string if present. */
};
Sensitivity/Integrity Extension
struct sadbsens {
SunOS 5.11 Last change: 6 May 2008 4
Protocols pfkey(7P)
uint16t sadbsenslen;
uint16t sadbsensexttype; /* SENSITIVITY */
uint32t sadbsensdpd;
uint8t sadbsenssenslevel;
uint8t sadbsenssenslen; /* 64-bit words */
uint8t sadbsensinteglevel;
uint8t sadbsensinteglen; /* 64-bit words */
uint32t sadbsensreserved;
/*
* followed by two uint64t arrays
* uint64t sadbsensbitmap[sensbitmaplen];
* uint64t integbitmap[integbitmaplen];
*/
};
Proposal Extension
struct sadbprop {
uint16t sadbproplen;
uint16t sadbpropexttype; /* PROPOSAL, XEPROP */
uint8t sadbpropreplay;
uint8t sadbXpropereserved;
uint16t sadbxpropnumecombs;
/* Followed by sadbcomb[] array or sadbecomb[] array. */
};
Combination Instance for a Proposal
struct sadbcomb {
uint8t sadbcombauth;
uint8t sadbcombencrypt;
uint16t sadbcombflags;
uint16t sadbcombauthminbits;
uint16t sadbcombauthmaxbits;
uint16t sadbcombencryptminbits;
uint16t sadbcombencryptmaxbits;
uint32t sadbcombreserved;
uint32t sadbcombsoftallocations;
uint32t sadbcombhardallocations;
uint64t sadbcombsoftbytes;
uint64t sadbcombhardbytes;
uint64t sadbcombsoftaddtime;
uint64t sadbcombhardaddtime;
uint64t sadbcombsoftusetime;
uint64t sadbcombhardusetime;
};
Extended Combination
struct sadbxecomb {
uint8t sadbxecombnumalgs;
uint8t sadbxecombreserved;
SunOS 5.11 Last change: 6 May 2008 5
Protocols pfkey(7P)
uint16t sadbxecombflags; /* E.g. PFS? */
uint32t sadbxecombreserved2;
uint32t sadbxecombsoftallocations;
uint32t sadbxecombhardallocations;
uint64t sadbxecombsoftbytes;
uint64t sadbxecombhardbytes;
uint64t sadbxecombsoftaddtime;
uint64t sadbxecombhardaddtime;
uint64t sadbxecombsoftusetime;
uint64t sadbxecombhardusetime;
};
Extended Combination Algorithm Descriptors
struct sadbxalgdesc {
uint8t sadbxalgdescsatype; /* ESP, AH, etc. */
uint8t sadbxalgdescalgtype; /* AUTH, CRYPT, COMPRES */
uint8t sadbxalgdescalg; /* DES, 3DES, MD5, etc. */
uint8t sadbxalgdescreserved;
uint16t sadbxalgdescminbits; /* Bit strengths. */
uint16t sadbxalgdescmaxbits;
};
Extended Register
struct sadbxereg {
uint16t sadbxereglen;
uint16t sadbxeregexttype; /* XEREG */
uint8t sadbxeregsatypes[4]; /* Array of SA types, 0-terminated.
};
Key Management Cookie
struct sadbxkmc {
uint16t sadbxkmclen;
uint16t sadbxkmcexttype; /* XKMCOKIE */
uint32t sadbxkmcproto; /* KM protocol */
uint32t sadbxkmccookie; /* KMP-specific */
uint32t sadbxkmcreserved; /* Reserved; must be zero */
};
Supported Algorithms Extension
struct sadbsupported {
uint16t sadbsupportedlen;
uint16t sadbsupportedexttype;
uint32t sadbsupportedreserved;
};
Algorithm Instance
struct sadbalg {
SunOS 5.11 Last change: 6 May 2008 6
Protocols pfkey(7P)
uint8t sadbalgid; /* Algorithm type. */
uint8t sadbalgivlen; /* IV len, in bits */
uint16t sadbalgminbits; /* Min. key len (in bits) */
uint16t sadbalgmaxbits; /* Max. key length */
uint16t sadbalgreserved;
};
SPI Extension Range
struct sadbspirange {
uint16t sadbspirangelen;
uint16t sadbspirangeexttype; /* SPIRANGE */
uint32t sadbspirangemin
uint32t sadbspirangemax;
uint32t sadbspirangereserved;
};
Security Association Pair Extension
struct sadbxpair {
uint16t sadbxpairlen;
uint16t sadbxpairexttype; /* SADBXEXTPAIR */
uint32t sadbxpairspi; /* SPI of paired SA */
};
Message Use and Behavior
Each message has a behavior. A behavior is defined as where
the initial message travels, for example, user to kernel,
and what subsequent actions are expected to take place. Con-
tents of messages are illustrated as:
The SA extension is sometimes used only for its SPI field.
If all other fields must be ignored, this is represented by
SA(*).
The lifetime extensions are represented with one to three
letters after the word lifetime, representing (H)ARD,
(S)OFT, and (C)URENT.
The address extensions are represented with one to three
letters after the word "address," representing (S)RC, (D)ST,
(Nl)NAT-T local, (Nr)NAT-T remote, (Is)Inner source, and
(Id)Inner destination.
SunOS 5.11 Last change: 6 May 2008 7
Protocols pfkey(7P)
Source and destination address extensions reflect outer-
header selectors for an IPsec SA. An SA is inbound or out-
bound depending on which of the source or destination
address is local to the node. Inner-source and inner-
destination selectors represent inner-header selectors for
Tunnel Mode SAs. A Tunnel Mode SA must have either
IPROTOENCAP or IPROTOIPV6 in its outer-headers as proto-
col selector, in addition to filled-in Inner-address exten-
sions.
NAT-T local and NAT-T remote addresses store local and
remote ports used for ESP-in-UDP encapsulation. A non-zero
local NAT-T address extension represents the local node's
external IP address if it is not equivalent to the SA's
local address. A non-zero remote NAT-T address represents a
peer's behind-a-NAT address if it is not equivalent to the
SA's remote address. An SA with NAT-T extensions will
protect-and-transmit outbound traffic. Processing of
inbound NAT-T traffic requires a UDP socket bound to the
appropriate local port and it must have the
UDPNATENDPOINT (see udp(7P)) socket option enabled.
Note that when an error occurs, only the base header is
sent. In the event of an error, an extended diagnostic may
be set (see DIAGNOSTICS). Typical errors include:
EINVAL Various message improprieties, including SPI
ranges that are malformed, weak keys, and others.
If EINVAL is returned, an application should look
at the sadbxmsgdiagnostic field of the
sadbmsg structure. It contains one of many pos-
sible causes for EINVAL. See net/pfkeyv2.h for
values, all of the form SADBXDIAGNOSTIC.
ENOMEM Needed memory was not available.
ENSGSIZ Message exceeds the maximum length allowed.
EXIST SA (that is being added or created with GETSPI)
already exists.
ESRCH SA could not be found.
SunOS 5.11 Last change: 6 May 2008 8
Protocols pfkey(7P)
The following are examples of message use and behavior:
SADBGETSPI
Send a SADBGETSPI message from a user process to the ker-
nel.
The kernel returns the SADBGETSPI message to all listening
processes.
SADBUPDATE
Send a SADBUPDATE message from a user process to the ker-
nel.
The kernel returns the SADBUPDATE message to all listening
processes.
Adding a sadbxpair extension to an SADBUPDATE or SADBAD
message will update the security association pair linkage
with the SPI of the security association contained in that
extension. The resulting security association "pair" can be
updated or as a single entity using the SADBXUPDATEPAIR or
SADBXDELPAIR message types.
SADBAD
Send a SADBAD message from a user process to the kernel.
The kernel returns the SADBAD message to all listening
processes.
SunOS 5.11 Last change: 6 May 2008 9
Protocols pfkey(7P)
SADBXUPDATEPAIR
Send a SADBXUPDATEPAIR message from a user process to the
kernel. This message type is used to update the lifetime
values of a security association and the lifetime values of
the security association it is paired with.
SADBDELETE SADBXDELPAIR
Send a SADBDELETE message from a user process to the ker-
nel. The SADBXDELPAIR message type will request deletion
of the security association and the security association it
is paired with.
The kernel returns the SADBDELETE message to all listening
processes.
SADBGET
Send a SADBGET message from a user process to the kernel.
The kernel returns the SADBGET message to the socket that
sent the SADBGET message.
SADBACQUIRE
The kernel sends a SADBACQUIRE message to registered sock-
ets. Note that any GETSPI, AD, or UPDATE calls in reaction
to an ACQUIRE must fill in the sadbmsgseq of those mes-
sages with the one in the ACQUIRE message. The address (SD)
extensions must have the port fields filled in with the port
numbers of the session requiring keys if appropriate.
SunOS 5.11 Last change: 6 May 2008 10
Protocols pfkey(7P)
Extended ACQUIRE will have a slightly different format. The
sadbmsgsatype field is 0, and the extension contains the
desired combination(s) of security protocols.
If key management fails, send an SADBACQUIRE to indicate
failure.
SADBXINVERSEACQUIRE
For inbound Key Management processing, a Key Management
application may wish to consult the kernel for its policy.
The application should send to the kernel:
The kernel returns a message similar to a kernel-generated
extended ACQUIRE:
SADBREGISTER
Send a SADBREGISTER message from a user process to the ker-
nel.
The kernel returns the SADBREGISTER message to registered
sockets, with algorithm types supported by the kernel being
indicated in the supported algorithms field. Note that this
message may arrive asynchronously due to an algorithm being
loaded or unloaded into a dynamically linked kernel.
There is also the extended REGISTER, which will allow this
process to receive extended ACQUIREs.
SunOS 5.11 Last change: 6 May 2008 11
Protocols pfkey(7P)
Which returns a series of SADBREGISTER replies (one for
each security protocol registered) from the kernel.
SADBEXPIRE
The kernel sends a SADBEXPIRE message to all listeners when
the soft limit of a security association has been expired.
SADBFLUSH
Send a SADBFLUSH message from a user process to the kernel.
The kernel returns the SADBFLUSH message to all listening
sockets.
SADBDUMP
Send a SADBDUMP message from a user process to the kernel.
Several SADBDUMP messages will return from the kernel to
the sending socket.
To mark the end of a dump a single base header arrives with
its sadbmdgseq set to 0.
SADBXPROMISC
Send a SADBXPROMISC message from a user process to the
kernel.
SunOS 5.11 Last change: 6 May 2008 12
Protocols pfkey(7P)
The kernel returns the SADBXPROMISC message to all listen-
ing processes.
DIAGNOSTICS
The message returning from the kernel will contain a diag-
nostic value in the base message header, the diagnostic
value will indicate if action requested by the original mes-
sage was a success.
Diagnostic Values:
#define SADBXDIAGNOSTICNONE 0
#define SADBXDIAGNOSTICUNKNOWNMSG 1
#define SADBXDIAGNOSTICUNKNOWNEXT 2
#define SADBXDIAGNOSTICBADEXTLEN 3
#define SADBXDIAGNOSTICUNKNOWNSATYPE 4
#define SADBXDIAGNOSTICSATYPENEDED 5
#define SADBXDIAGNOSTICNOSADBS 6
#define SADBXDIAGNOSTICNOEXT 7
/* Bad address family value */
#define SADBXDIAGNOSTICBADSRCAF 8
/* in sockaddr->safamily. */
#define SADBXDIAGNOSTICBADSTAF 9
/* These two are synonyms. */
#define SADBXDIAGNOSTICBADPROXYAF 10
#define SADBXDIAGNOSTICBADINERSRCAF 10
#define SADBXDIAGNOSTICAFMISMATCH 11
#define SADBXDIAGNOSTICBADSRC 12
#define SADBXDIAGNOSTICBADST 13
#define SADBXDIAGNOSTICALOCHSER 14
#define SADBXDIAGNOSTICBYTESHSER 15
#define SADBXDIAGNOSTICADTIMEHSER 16
#define SADBXDIAGNOSTICUSETIMEHSER 17
#define SADBXDIAGNOSTICMISINGSRC 18
#define SADBXDIAGNOSTICMISINGDST 19
#define SADBXDIAGNOSTICMISINGSA 20
#define SADBXDIAGNOSTICMISINGEKEY 21
#define SADBXDIAGNOSTICMISINGAKEY 22
#define SADBXDIAGNOSTICMISINGRANGE 23
SunOS 5.11 Last change: 6 May 2008 13
Protocols pfkey(7P)
#define SADBXDIAGNOSTICDUPLICATESRC 24
#define SADBXDIAGNOSTICDUPLICATEDST 25
#define SADBXDIAGNOSTICDUPLICATESA 26
#define SADBXDIAGNOSTICDUPLICATEKEY 27
#define SADBXDIAGNOSTICDUPLICATEAKEY 28
#define SADBXDIAGNOSTICDUPLICATERANGE 29
#define SADBXDIAGNOSTICMALFORMEDSRC 30
#define SADBXDIAGNOSTICMALFORMEDST 31
#define SADBXDIAGNOSTICMALFORMEDSA 32
#define SADBXDIAGNOSTICMALFORMEDEKEY 33
#define SADBXDIAGNOSTICMALFORMEDAKEY 34
#define SADBXDIAGNOSTICMALFORMEDRANGE 35
#define SADBXDIAGNOSTICAKEYPRESENT 36
#define SADBXDIAGNOSTICEKEYPRESENT 37
#define SADBXDIAGNOSTICPROPRESENT 38
#define SADBXDIAGNOSTICSUPRESENT 39
#define SADBXDIAGNOSTICBADALG 40
#define SADBXDIAGNOSTICBADEALG 41
#define SADBXDIAGNOSTICBADSAFLAGS 42
#define SADBXDIAGNOSTICBADSASTATE 43
#define SADBXDIAGNOSTICBADAKEYBITS 44
#define SADBXDIAGNOSTICBADEKEYBITS 45
#define SADBXDIAGNOSTICENCRNOTSUP 46
#define SADBXDIAGNOSTICWEAKEKEY 47
#define SADBXDIAGNOSTICWEAKAKEY 48
#define SADBXDIAGNOSTICDUPLICATEKMP 49
#define SADBXDIAGNOSTICDUPLICATEKMC 50
#define SADBXDIAGNOSTICMISINGNATLOC 51
#define SADBXDIAGNOSTICMISINGNATREM 52
#define SADBXDIAGNOSTICDUPLICATENATLOC 53
#define SADBXDIAGNOSTICDUPLICATENATREM 54
#define SADBXDIAGNOSTICMALFORMEDNATLOC 55
#define SADBXDIAGNOSTICMALFORMEDNATREM 56
#define SADBXDIAGNOSTICDUPLICATENATPORTS 57
#define SADBXDIAGNOSTICMISINGINERSRC 58
#define SADBXDIAGNOSTICMISINGINERDST 59
#define SADBXDIAGNOSTICDUPLICATEINERSRC 60
#define SADBXDIAGNOSTICDUPLICATEINERDST 61
#define SADBXDIAGNOSTICMALFORMEDINERSRC 62
#define SADBXDIAGNOSTICMALFORMEDINERDST 63
#define SADBXDIAGNOSTICPREFIXINERSRC 64
#define SADBXDIAGNOSTICPREFIXINERDST 65
#define SADBXDIAGNOSTICBADINERDSTAF 66
SunOS 5.11 Last change: 6 May 2008 14
Protocols pfkey(7P)
#define SADBXDIAGNOSTICINERAFMISMATCH 67
#define SADBXDIAGNOSTICBADNATREMAF 68
#define SADBXDIAGNOSTICBADNATLOCAF 69
#define SADBXDIAGNOSTICPROTOMISMATCH 70
#define SADBXDIAGNOSTICINERPROTOMISMATCH 71
#define SADBXDIAGNOSTICDUALPORTSETS 72
#define SADBXDIAGNOSTICPAIRINAPROPRIATE 73
#define SADBXDIAGNOSTICPAIRADMISMATCH 74
#define SADBXDIAGNOSTICPAIRALREADY 75
#define SADBXDIAGNOSTICPAIRSANOTFOUND 76
#define SADBXDIAGNOSTICBADSADIRECTION 77
#define SADBXDIAGNOSTICSANOTFOUND 78
#define SADBXDIAGNOSTICSAEXPIRED 79
ATRIBUTES
See attributes(5) for descriptions of the following attri-
butes:
ATRIBUTE TYPE ATRIBUTE VALUE
Availability SUNWcsr
Interface Stability Evolving
SEE ALSO
in.iked(1M), ipseckey(1M), ipsec(7P), ipsecah(7P),
ipsecesp(7P), route(7P), udp(7P)
McDonald, D.L., Metz, C.W., and Phan, B.G., RFC 2367, PFKEY
Key Management API, Version 2, The Internet Society, July
1998.
NOTES
Time-based lifetimes may not expire with exact precision in
seconds because kernel load may affect the aging of SA's.
SunOS 5.11 Last change: 6 May 2008 15
|