[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
PF_POLICY, the solaris version.
Here are some excerpts from the solaris <net/pfpolicy.h> header file, for purposes of
discussion; this header is shipped as part of solaris 9 and later.
This describes the format of messages written to and read from a PF_POLICY socket,
created via
s = socket(SOCK_RAW, PF_POLICY, PF_POLICY_V1);
As a disclaimer for folks interested in using this on Solaris:
This is considered to be 'project private' interface -- which means that Sun
reserves the right to make incompatible changes to it in the future, even as
part of bugfixes/patches (for instance, to bring it into compliance with
a common version).
The high level encoding used here is very similar to PF_KEY; it does change
styles significantly to encode actions, however; see the block comment for more
details.
Writing a draft on this interface has been on my todo list for years. I'm sending
this out in the hopes that text generated during the following discussion will
form the basis of this draft....
- Bill
#define PF_POLICY_V1 1
#define PF_POLICY_REVISION 200304L
/*
* Base PF_POLICY message header. Each request/response starts with
* one of these, followed by some number of extensions. Each
* extension type appears at most once in a message. spd_msg_len
* contains the total length of the message including header.
*/
typedef struct spd_msg
{
uint8_t spd_msg_version; /* PF_POLICY_V1 */
uint8_t spd_msg_type; /* ADD, DELETE, QUERY, ... */
uint8_t spd_msg_errno; /* Unix errno space; mbz on request */
uint8_t spd_msg_spdid; /* which policy db instance */
uint16_t spd_msg_len; /* in 64-bit words */
uint16_t spd_msg_diagnostic; /* additional error reason */
/* Union is for guaranteeing 64-bit alignment. */
union {
struct {
uint32_t spd_msg_useq; /* set by sender */
uint32_t spd_msg_upid; /* set by sender */
} spd_msg_actual;
uint64_t spd_msg_alignment;
} spd_msg_u;
#define spd_msg_seq spd_msg_u.spd_msg_actual.spd_msg_useq
#define spd_msg_pid spd_msg_u.spd_msg_actual.spd_msg_upid
} spd_msg_t;
/*
* Command numbers, found in spd_msg_type.
*/
#define SPD_RESERVED 0
#define SPD_MIN 1
#define SPD_FLUSH 1
#define SPD_ADDRULE 2
#define SPD_DELETERULE 3
#define SPD_FLIP 4
#define SPD_LOOKUP 5
#define SPD_DUMP 6
#define SPD_CLONE 7
#define SPD_ALGLIST 8
#define SPD_DUMPALGS 9
#define SPD_UPDATEALGS 10
#define SPD_MAX 10
/*
* Well-known policy db instances, found in spd_msg_spdid
*/
#define SPD_ACTIVE 0 /* The currently active instance */
#define SPD_STANDBY 1 /* "on deck" standby SPD */
/*
* The spd_msg_t is followed by extensions, which start with the
* following header; each extension structure includes the length and
* type fields internally as an overlay to simplify parsing and
* construction.
*/
typedef struct spd_ext
{
/* Union is for guaranteeing 64-bit alignment. */
union {
struct {
uint16_t spd_ext_ulen; /* in 64-bit words */
uint16_t spd_ext_utype; /* 0 is reserved */
} spd_ext_actual;
uint64_t spd_ext_alignment;
} spd_ext_u;
#define spd_ext_len spd_ext_u.spd_ext_actual.spd_ext_ulen
#define spd_ext_type spd_ext_u.spd_ext_actual.spd_ext_utype
} spd_ext_t;
/*
* Extension numbers, found in spd_ext_type.
*/
#define SPD_EXT_LCLPORT 1
#define SPD_EXT_REMPORT 2
#define SPD_EXT_PROTO 3
#define SPD_EXT_LCLADDR 4
#define SPD_EXT_REMADDR 5
#define SPD_EXT_ACTION 6
#define SPD_EXT_RULE 7
#define SPD_EXT_RULESET 8
#define SPD_EXT_ICMP_TYPECODE 9
#define SPD_EXT_MAX 9
/*
* base policy rule (attributes which every rule has)
*
* spd_rule_index MBZ on a SPD_ADD, and is assigned by the kernel.
* subsequent deletes can operate either by specifying selectors or by
* specifying a non-zero rule index.
*/
struct spd_rule
{
uint16_t spd_rule_len;
uint16_t spd_rule_type; /* SPD_EXT_RULE */
uint32_t spd_rule_priority;
uint32_t spd_rule_flags; /* INBOUND, OUTBOUND, ... */
uint32_t spd_rule_unused;
uint64_t spd_rule_index; /* unique rule identifier. */
};
/*
* Flags for spd_rule.spd_rule_flags
*/
#define SPD_RULE_FLAG_INBOUND 0x0001
#define SPD_RULE_FLAG_OUTBOUND 0x0002
/*
* Address selectors. Different from PF_KEY because we want a
* more precise format for wildcards on ports/protocol.
*/
typedef struct spd_address {
/* Union is for guaranteeing 64-bit alignment. */
union {
struct {
uint16_t spd_address_ulen;
uint16_t spd_address_uexttype; /* SRC, DST */
uint8_t spd_address_uaf; /* address family. */
uint8_t spd_address_uprefixlen; /* Prefix len (bits). */
uint16_t spd_address_ureserved2; /* Padding */
} spd_address_actual;
uint64_t spd_address_alignment;
} spd_address_u;
/*
* .. followed by 4 bytes of IPv4 or 16 bytes of IPv6 address,
* padded up to next uint64_t
*/
#define spd_address_len \
spd_address_u.spd_address_actual.spd_address_ulen
#define spd_address_exttype \
spd_address_u.spd_address_actual.spd_address_uexttype
#define spd_address_af \
spd_address_u.spd_address_actual.spd_address_uaf
#define spd_address_prefixlen \
spd_address_u.spd_address_actual.spd_address_uprefixlen
#define spd_address_reserved2 \
spd_address_u.spd_address_actual.spd_address_ureserved2
} spd_address_t;
/*
* Protocol selector
*/
struct spd_proto
{
/* Union is for guaranteeing 64-bit alignment. */
union {
struct {
uint16_t spd_proto_ulen;
uint16_t spd_proto_uexttype; /* PROTO */
uint8_t spd_proto_unumber; /* IPPROTO_* */
uint8_t spd_proto_ureserved1; /* pad */
uint16_t spd_proto_ureserved2; /* pad */
} spd_proto_actual;
uint64_t spd_proto_alignment;
} spd_proto_u;
#define spd_proto_len spd_proto_u.spd_proto_actual.spd_proto_ulen
#define spd_proto_exttype spd_proto_u.spd_proto_actual.spd_proto_uexttype
#define spd_proto_number spd_proto_u.spd_proto_actual.spd_proto_unumber
#define spd_proto_reserved1 spd_proto_u.spd_proto_actual.spd_proto_ureserved1
#define spd_proto_reserved2 spd_proto_u.spd_proto_actual.spd_proto_ureserved2
};
/*
* Port selector. We only support minport==maxport at present.
*/
struct spd_portrange
{
/* Union is for guaranteeing 64-bit alignment. */
union {
struct {
uint16_t spd_ports_ulen;
uint16_t spd_ports_uexttype; /* LCLPORT, REMPORT */
uint16_t spd_ports_uminport; /* min port */
uint16_t spd_ports_umaxport; /* max port */
} spd_ports_actual;
uint64_t spd_ports_alignment;
} spd_ports_u;
#define spd_ports_len spd_ports_u.spd_ports_actual.spd_ports_ulen
#define spd_ports_exttype spd_ports_u.spd_ports_actual.spd_ports_uexttype
#define spd_ports_minport spd_ports_u.spd_ports_actual.spd_ports_uminport
#define spd_ports_maxport spd_ports_u.spd_ports_actual.spd_ports_umaxport
};
/*
* ICMP type selector.
*/
struct spd_typecode
{
/* Union is for guaranteeing 64-bit alignment. */
union {
struct {
uint16_t spd_typecode_ulen;
uint16_t spd_typecode_uexttype; /* ICMP_TYPECODE */
uint8_t spd_typecode_utype;
uint8_t spd_typecode_utype_end;
uint8_t spd_typecode_ucode;
uint8_t spd_typecode_ucode_end;
} spd_typecode_actual;
uint64_t spd_typecode_alignment;
} spd_typecode_u;
#define spd_typecode_len \
spd_typecode_u.spd_typecode_actual.spd_typecode_ulen
#define spd_typecode_exttype \
spd_typecode_u.spd_typecode_actual.spd_typecode_uexttype
#define spd_typecode_type \
spd_typecode_u.spd_typecode_actual.spd_typecode_utype
#define spd_typecode_type_end \
spd_typecode_u.spd_typecode_actual.spd_typecode_utype_end
#define spd_typecode_code \
spd_typecode_u.spd_typecode_actual.spd_typecode_ucode
#define spd_typecode_code_end \
spd_typecode_u.spd_typecode_actual.spd_typecode_ucode_end
};
/*
* Actions, specifying what happens to packets which match selectors.
* This extension is followed by some number of spd_attribute tag-value pairs
* which encode one or more alternative policies; see below for
* the encoding used.
*/
struct spd_ext_actions
{
/* Union is for guaranteeing 64-bit alignment. */
union {
struct {
uint16_t spd_actions_ulen;
uint16_t spd_actions_uexttype; /* ACTION */
uint16_t spd_actions_ucount; /* # of alternatives */
uint16_t spd_actions_ureserved;
} spd_actions_actual;
uint64_t spd_actions_alignment;
} spd_actions_u;
#define spd_actions_len \
spd_actions_u.spd_actions_actual.spd_actions_ulen
#define spd_actions_exttype \
spd_actions_u.spd_actions_actual.spd_actions_uexttype
#define spd_actions_count \
spd_actions_u.spd_actions_actual.spd_actions_ucount
#define spd_actions_reserved \
spd_actions_u.spd_actions_actual.spd_actions_ureserved
};
/*
* Extensible encoding for requested SA attributes.
* To allow additional attributes to be added, we use a simple-to-interpret
* (tag, value) encoding to fill in attributes in a list of alternatives.
*
* We fill in alternatives one at a time, starting with most-preferred,
* proceeding to least-preferred.
*
* Conceptually, we are filling in attributes of a "template", and
* then copying that template value into the list of alternatives when
* we see a SPD_ATTR_END or SPD_ATTR_NEXT.
*
* The template is not changed by SPD_ATTR_NEXT, so that attributes common to
* all alternatives need only be mentioned once.
*
* spd_actions_count is the maximum number of alternatives present; it
* should be one greater than the number of SPD_ATTR_NEXT opcodes
* present in the sequence.
*/
struct spd_attribute
{
union {
struct {
uint32_t spd_attr_utag;
uint32_t spd_attr_uvalue;
} spd_attribute_actual;
uint64_t spd_attribute_alignment;
} spd_attribute_u;
#define spd_attr_tag spd_attribute_u.spd_attribute_actual.spd_attr_utag
#define spd_attr_value spd_attribute_u.spd_attribute_actual.spd_attr_uvalue
};
#define SPD_ATTR_NOP 0x00000000 /* space filler */
#define SPD_ATTR_END 0x00000001 /* end of description */
#define SPD_ATTR_EMPTY 0x00000002 /* reset template to default */
#define SPD_ATTR_NEXT 0x00000003 /* start filling next alternative */
#define SPD_ATTR_TYPE 0x00000100
#define SPD_ATTR_FLAGS 0x00000101
#define SPD_ATTR_AH_AUTH 0x00000102
#define SPD_ATTR_ESP_ENCR 0x00000103
#define SPD_ATTR_ESP_AUTH 0x00000104
#define SPD_ATTR_ENCR_MINBITS 0x00000105
#define SPD_ATTR_ENCR_MAXBITS 0x00000106
#define SPD_ATTR_AH_MINBITS 0x00000107
#define SPD_ATTR_AH_MAXBITS 0x00000108
#define SPD_ATTR_LIFE_SOFT_TIME 0x00000109
#define SPD_ATTR_LIFE_HARD_TIME 0x0000010a
#define SPD_ATTR_LIFE_SOFT_BYTES 0x0000010b
#define SPD_ATTR_LIFE_HARD_BYTES 0x0000010c
#define SPD_ATTR_KM_PROTO 0x0000010d
#define SPD_ATTR_KM_COOKIE 0x0000010e
#define SPD_ATTR_REPLAY_DEPTH 0x0000010f
#define SPD_ATTR_ESPA_MINBITS 0x00000110
#define SPD_ATTR_ESPA_MAXBITS 0x00000111
#define SPD_ATTR_ENCR_DEFBITS 0x00000112
#define SPD_ATTR_ENCR_INCRBITS 0x00000113
#define SPD_ATTR_AH_DEFBITS 0x00000114
#define SPD_ATTR_AH_INCRBITS 0x00000115
#define SPD_ATTR_ESPA_DEFBITS 0x00000116
#define SPD_ATTR_ESPA_INCRBITS 0x00000117
#define SPD_ATTR_ALG_ID 0x00000118
#define SPD_ATTR_ALG_PROTO 0x00000119
#define SPD_ATTR_ALG_INCRBITS 0x0000011a
#define SPD_ATTR_ALG_NKEYSIZES 0x0000011b
#define SPD_ATTR_ALG_KEYSIZE 0x0000011c
#define SPD_ATTR_ALG_NBLOCKSIZES 0x0000011d
#define SPD_ATTR_ALG_BLOCKSIZE 0x0000011e
#define SPD_ATTR_ALG_MECHNAME 0x0000011f
#define SPD_ATTR_PROTO_ID 0x00000120
#define SPD_ATTR_PROTO_EXEC_MODE 0x00000121
/*
* Minimum, maximum key lengths in bits.
*/
#define SPD_MIN_MINBITS 0x0000
#define SPD_MAX_MAXBITS 0xffff
/*
* IPsec action types (in SPD_ATTR_TYPE attribute)
*/
#define SPD_ACTTYPE_DROP 0x0001
#define SPD_ACTTYPE_PASS 0x0002
#define SPD_ACTTYPE_IPSEC 0x0003
/*
* Action flags (in SPD_ATTR_FLAGS attribute)
*/
#define SPD_APPLY_AH 0x0001
#define SPD_APPLY_ESP 0x0002
#define SPD_APPLY_SE 0x0004 /* self-encapsulation */
#define SPD_APPLY_COMP 0x0008 /* compression; NYI */
#define SPD_APPLY_UNIQUE 0x0010 /* unique per-flow SA */
#define SPD_APPLY_BYPASS 0x0020 /* bypass policy */
#define SPD_APPLY_ESPA 0x0040 /* ESP authentication */
/*
* SPD_DUMP protocol:
*
* We do not want to force an stack to have to read-lock the entire
* SPD for the duration of the dump, but we want management apps to be
* able to get a consistent snapshot of the SPD.
*
* Therefore, we make optimistic locking assumptions.
*
* The response to a SPD_DUMP request consists of multiple spd_msg
* records, all with spd_msg_type == SPD_DUMP and spd_msg_{seq,pid}
* matching the request.
*
* There is one header, then a sequence of policy rule records (one
* rule per record), then a trailer.
*
* The header and trailer both contain a single SPD_EXT_RULESET
* containing a version number and rule count. The dump was "good" if
* header version == trailer version, and the number of rules read by
* the application matches the rule count in the trailer. The rule
* count in the header is unused and should be set to zero.
*
* In between, each rule record contains a set of extensions which, if
* used in an SPD_ADD request, would recreate an equivalent rule.
*
* If rules were added to the SPD during the dump, the dump may be
* truncated or otherwise incomplete; the management application
* should re-try the dump in this case.
*/
/*
* Ruleset extension, used at the start and end of a SPD_DUMP.
*/
typedef struct spd_ruleset_ext
{
uint16_t spd_ruleset_len; /* 2 x 64 bits */
uint16_t spd_ruleset_type; /* SPD_EXT_RULESET */
uint32_t spd_ruleset_count; /* only valid in trailer */
uint64_t spd_ruleset_version; /* version number */
} spd_ruleset_ext_t;
/*
* Diagnostic codes. These supplement error messages. Be sure to
* update libipsecutil's spdsock_diag() if you change any of these.
*/
#define SPD_DIAGNOSTIC_NONE 0
#define SPD_DIAGNOSTIC_UNKNOWN_EXT 1
#define SPD_DIAGNOSTIC_BAD_EXTLEN 2
#define SPD_DIAGNOSTIC_NO_RULE_EXT 3
#define SPD_DIAGNOSTIC_BAD_ADDR_LEN 4
#define SPD_DIAGNOSTIC_MIXED_AF 5
#define SPD_DIAGNOSTIC_ADD_NO_MEM 6
#define SPD_DIAGNOSTIC_ADD_WRONG_ACT_COUNT 7
#define SPD_DIAGNOSTIC_ADD_BAD_TYPE 8
#define SPD_DIAGNOSTIC_ADD_BAD_FLAGS 9
#define SPD_DIAGNOSTIC_ADD_INCON_FLAGS 10
#define SPD_DIAGNOSTIC_MALFORMED_LCLPORT 11
#define SPD_DIAGNOSTIC_DUPLICATE_LCLPORT 12
#define SPD_DIAGNOSTIC_MALFORMED_REMPORT 13
#define SPD_DIAGNOSTIC_DUPLICATE_REMPORT 14
#define SPD_DIAGNOSTIC_MALFORMED_PROTO 15
#define SPD_DIAGNOSTIC_DUPLICATE_PROTO 16
#define SPD_DIAGNOSTIC_MALFORMED_LCLADDR 17
#define SPD_DIAGNOSTIC_DUPLICATE_LCLADDR 18
#define SPD_DIAGNOSTIC_MALFORMED_REMADDR 19
#define SPD_DIAGNOSTIC_DUPLICATE_REMADDR 20
#define SPD_DIAGNOSTIC_MALFORMED_ACTION 21
#define SPD_DIAGNOSTIC_DUPLICATE_ACTION 22
#define SPD_DIAGNOSTIC_MALFORMED_RULE 23
#define SPD_DIAGNOSTIC_DUPLICATE_RULE 24
#define SPD_DIAGNOSTIC_MALFORMED_RULESET 25
#define SPD_DIAGNOSTIC_DUPLICATE_RULESET 26
#define SPD_DIAGNOSTIC_INVALID_RULE_INDEX 27
#define SPD_DIAGNOSTIC_BAD_SPDID 28
#define SPD_DIAGNOSTIC_BAD_MSG_TYPE 29
#define SPD_DIAGNOSTIC_UNSUPP_AH_ALG 30
#define SPD_DIAGNOSTIC_UNSUPP_ESP_ENCR_ALG 31
#define SPD_DIAGNOSTIC_UNSUPP_ESP_AUTH_ALG 32
#define SPD_DIAGNOSTIC_UNSUPP_AH_KEYSIZE 33
#define SPD_DIAGNOSTIC_UNSUPP_ESP_ENCR_KEYSIZE 34
#define SPD_DIAGNOSTIC_UNSUPP_ESP_AUTH_KEYSIZE 35
#define SPD_DIAGNOSTIC_NO_ACTION_EXT 36
#define SPD_DIAGNOSTIC_ALG_ID_RANGE 37
#define SPD_DIAGNOSTIC_ALG_NUM_KEY_SIZES 38
#define SPD_DIAGNOSTIC_ALG_NUM_BLOCK_SIZES 39
#define SPD_DIAGNOSTIC_ALG_MECH_NAME_LEN 40
#define SPD_DIAGNOSTIC_ALG_IPSEC_NOT_LOADED 41
#define SPD_DIAGNOSTIC_MALFORMED_ICMP_TYPECODE 42
#define SPD_DIAGNOSTIC_DUPLICATE_ICMP_TYPECODE 43