Name

libpcpd — port-control-protocol server library

FUNCTIONS

#include <pcpd.h>
int pcpd_cgn_init( pcpd_t *pcpd,
  int argc,
  char *argv[]);
 
int pcpd_cgn_close( pcpd_t *pcpd);
 
int pcpd_cgn_register( pcpd_t *pcpd,
  pcpd_announce type * announce_callback,
  pcpd_update type * update_callback,
  pcpd_uncache type * uncache_callback);
 
int pcpd_lib_init( pcpd_t *pcpd);
 
int pcpd_lib_close( const pcpd_t *pcpd);
 
int pcpd_lib_runonce( const pcpd_t *pcpd,
  const pcpctx_t *ctx);
 
void pcpd_announce( const pcpd_t *pcpd,
  const pcpctx_t *ctx,
  const time_t epoch);
 
void pcpd_update( const pcpd_t *pcpd,
  const pcpctx_t *ctx,
  const uint8_t protocol,
  const uint8_t *intaddr,
  const uint8_t *extaddr,
  const uint16_t extport,
  const uint32_t lifetime);
 
void pcpd_update_recycle( const pcpd_t *pcpd,
  const pcpctx_t *ctx,
  const size_t length,
  const uint8_t *extaddr,
  const uint16_t extport,
  const uint32_t lifetime);
 
void pcpd_uncache( const pcpd_t *pcpd,
  const pcpctx_t *ctx);
 
const char *pcpd_strerror( int error);
 
const char *pcpd_id2str( const pcpd_t *pcpd,
  const uint8_t *sid);
 

METHODS

pcpd_t object
size_t (*pcpd_recvrequest)( const pcpd_t *pcpd,
  const pcpctx_t *ctx);
 
void (*pcpd_sendresponse)( const pcpd_t *pcpd,
  const pcpctx_t *ctx,
  const size_t length);
 
int (*pcpd_getsubscriber)( const pcpd_t *pcpd,
  const pcpctx_t *ctx,
  time_t *epoch);
 
int (*pcpd_authorize)( const pcpd_t *pcpd,
  const pcpctx_t *ctx,
  const size_t length,
  const size_t off3rdpty);
 
int (*pcpd_addmapping)( const pcpd_t *pcpd,
  const pcpctx_t *ctx,
  const uint8_t flags,
  const uint8_t proto,
  const uint8_t *intaddr,
  const uint16_t intport,
  uint8_t *extaddr,
  uint16_t *extport,
  uint32_t *lifetime);
 
int (*pcpd_delmapping)( const pcpd_t *pcpd,
  const pcpctx_t *ctx,
  const uint8_t proto,
  const uint8_t *intaddr,
  const uint16_t intport);
 
int (*pcpd_adddynamic)( const pcpd_t *pcpd,
  const pcpctx_t *ctx,
  const uint8_t proto,
  const uint8_t *intaddr,
  const uint16_t intport,
  const uint8_t *peeraddr,
  const uint16_t peerport,
  uint8_t *extaddr,
  uint16_t *extport,
  uint32_t *lifetime);
 
int (*pcpd_filter)( const pcpd_t *pcpd,
  const pcpctx_t *ctx,
  const uint8_t proto,
  const uint8_t *intaddr,
  const uint16_t intport,
  const uint8_t flags,
  const uint8_t count,
  const filter_t *filters);
 
void (*pcpd_incrcounter)( const pcpd_t *pcpd,
  const pcpstat_t code,
  const uint8_t idx);
 

DESCRIPTION

The _cgn_ functions are for the active/master mode of the library, i.e., when the main loop is run by the library itself. The _lib_ functions are for the passive/slave mode of the library, i.e., when the main loop is run by the CGN and pcpd_lib_runonce is called called when a PCP packet is intercepted.

pcpd_cgn_init calls for a PCP server handler initialization with stripped command line parameters.

pcpd_cgn_close releases a PCP server handler.

pcpd_cgn_register registers the pcpd_announce, pcpd_update, and pcpd_uncache callbacks.

pcpd_lib_init is called for a PCP server handler initialization. Note: this handler points to an object which must not be changed in its public part.

pcpd_lib_close is called to release a PCP server handler.

pcpd_lib_runonce is called to receive a PCP request, process it and send the response. The ctx is either a pointer to a context provided by the caller (note it is its responsibility to clear it between calls) or NULL (and the context will be allocated on the stack).

pcpd_announce callback is called when the CGN wants to notify subscribers that it has restarted or otherwise lost state. The pcpd_sendresponse method is used to send the ANNOUNCE response packet. If the packet is to be multicast, the pcpd_sendresponse method must take whatever steps are necessary to identify and route the packet - it might examine the ctx->client address, or it might look at the memory address of the ctx structure itself, or it might even have a separate pcpd_t instance for sending multicast, with a different pcpd_sendresponse method.

pcpd_update callback is called when the CGN has changed the external address of a mapping and wants to notify the client by sending an updated response. ctx->response must point to a buffer of at least 68 octets - large enough to hold a MAP response and a possible THIRD_PARTY option.

pcpd_update_recycle is called when the CGN has changed the external address of a mapping and wants to notify the client by sending an updated response. In this variant, ctx contains a pointer to a previous response (with a valid version/first byte) or a matching request. pcpd_update updates the response with the provided extaddr and extport.

pcpd_uncache callback is called when the CGN has destroyed or reset a subscriber so it must be removed from the cache.

pcpd_strerror (weak reference) translates an error to its human friendly description.

pcpd_id2str (weak reference) translates an subscriber identifier to its human friendly description (in fact IPv6 or IPv4 address).

pcpd_recvrequest blocks until a PCP request is available then returns it. On error the returned length is set to 0.

pcpd_sendresponse sends a PCP response.

pcpd_getsubscriber checks if a subscriber is authorized and fills the associated epoch (relative to now). It can create by side-effect the corresponding state in the CGN.

pcpd_authorize checks if a syntaxically correct request is authorized. off3rdpty in the ctx argument is the offset to the THIRD_PARTY option if present in the request or zero if not.

pcpd_addmapping creates if it doesn't already exist an explicit dynamic mapping. flags The PCPD_PREFER_FAILURE flag raise an error if the requested external port is not available, the PCPD_CREATE_AS_LOCKED flag modifies the returned code into PCPD_NEWMAPPING and postpones the activation of a new explicit dynamic mapping to the successful call to pcpd_filter.

pcpd_delmapping deletes matching explicit dynamic mapping. It never fails as no recovery is possible.

pcpd_adddynamic creates if it doesn't already exist an implicit dynamic mapping. It can raise an error if the requested external port is not available. On an EIM/EIF CGN remote peer address and port are ignored.

pcpd_filter associates remote filters to an explicit dynamic mapping. The PCPD_DELETE_FILTERS flag deletes first existing filters, the PCPD_UNLOCK_ON_SUCCESS flag activates new created explicit dynamic mappings on success, on failure they must be cleaned up.

pcpd_incrcounter increments the idx counter for the code (in PCPS_OPERATION, PCPS_RESULT and PCPS_OPTION) vector (abstract interface).

SERVER CGN TYPES

PCPD_TYPE_DSLITE

the CGN is a plain mode DS-Lite AFTR

PCPD_TYPE_NAT444

the CGN is the ISP part of a NAT444

PCPD_TYPE_NAT64

the CGN is a NAT64 (IPv6 to IPv4 translator)

PCPD_TYPE_46

the CGN is a NAT46 (IPv4 to IPv6 translator)

PCPD_TYPE_NPTv6

the CGN is a NPTv6 (IPv6/IPv6 NAT 1:1)

PCPD_TYPE_FW4

the CGN is an IPv4 firewall

PCPD_TYPE_FW6

the CGN is an IPv6 firewall

PCPD_TYPE_L2NAT

the CGN is a layer2 extended DS-Lite NAT

SERVER OPCODES

PCPD_OPCODE_ANNOUNCE

the ANNOUNCE opcode is supported

PCPD_OPCODE_MAP

the MAP opcode is supported

PCPD_OPCODE_PEER

the PEER opcode is supported

SERVER FLAGS

PCPD_MAPSRC

converts source addresses from/to IPv4 mapped IPv6 address format. Note this flag and related flags are used to check the syntax of requests, for instance a filter option with a 33 bit prefix length is rejected during parsing only when PCPD_MAPDST is set

PCPD_MAPINT

converts internal addresses from/to IPv4 mapped IPv6 address format

PCPD_MAPEXT

converts external addresses from/to IPv4 mapped IPv6 address format

PCPD_MAPDST

converts destination/remote peer addresses from/to IPv4 mapped IPv6 address format

PCPD_OTHERPROTO

allows other protocols than TCP and UDP (and zero)

PCPD_PORT0

allows internal port zero in not delete MAP request (requires PCPD_OTHERPROTO

PCPD_ONEONE

allows 1:1 style, i.e., protocol and internal port zero in not delete MAP request (requires PCPD_OTHERPROTO and PCPD_PORT0

PCPD_FIREWALL

the CGN is a firewall so internal and external ports and addresses must match (requires no PEER support and consistent (none or all) mapped address support)

PCPD_3RDPARTY

allows third party options in PCP requests. Note: this flag must be set for the other related third party option flags

PCPD_3RDPARTY_CPE

allows third party options in PCP requests only when the source address is 192.0.0.2

PCPD_3RDPARTY_AO

allows third party options in PCP requests only when they are all-zeroes.

PCPD_ANNOUNCE

enables the optional ANNOUNCE callback

PCPD_UPDATE

enables the optional MAP update callback

PCPD_CACHE

enables the optional subscriber caching by the PCP engine

RETURN CODES

PCPD_STATICMAPPING

already existing static mapping

PCPD_NEWMAPPING

a new mapping was created

PCPD_OK

OK

PCPD_ERR_INVAL

invalid arguments

PCPD_ERR_PROTOBASE

base for protocol errors

PCPD_ERR_UNSUPVERSION

unsupported version

PCPD_ERR_NOTAUTH

not authorized

PCPD_ERR_BADREQUEST

malformed request

PCPD_ERR_UNSUPOPCODE

unsupported opcode

PCPD_ERR_UNSUPOPTION

unsupported option

PCPD_ERR_BADOPTION

malformed option

PCPD_ERR_NETFAILURE

network failure

PCPD_ERR_NORESOURCES

out of resources

PCPD_ERR_UNSUPPROTO

unsupported protocol

PCPD_ERR_EXQUOTA

user exceeded quota

PCPD_ERR_CANTPROVIDE

cannot provide external address or port

PCPD_ERR_ADDRMISMATCH

address mismatch

PCPD_ERR_TOOMANYPEER

excessive number of remote peers

PCPD_ERR_PROCESSING

generic CGN processing error

SEE ALSO

libpcp(3)

AUTHOR

Internet Systems Consortium