Skip to content

Commit e0f0abd

Browse files
committed
pcp: added new module for Port Control Protocol (PCP)
1 parent 18bbd04 commit e0f0abd

File tree

12 files changed

+1517
-0
lines changed

12 files changed

+1517
-0
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ include $(LIBRE_MK)
2929
# List of modules
3030
MODULES += shim
3131
MODULES += trice
32+
MODULES += pcp
3233

3334
LIBS += -lm
3435

include/re_pcp.h

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
/**
2+
* @file re_pcp.h PCP - Port Control Protocol (RFC 6887)
3+
*
4+
* Copyright (C) 2010 - 2014 Creytiv.com
5+
*/
6+
7+
8+
/*
9+
* The following specifications are implemented:
10+
*
11+
* RFC 6887
12+
* draft-ietf-pcp-description-option-02
13+
* draft-cheshire-pcp-unsupp-family
14+
*
15+
*/
16+
17+
18+
/** PCP Version numbers */
19+
enum {
20+
PCP_VERSION = 2,
21+
};
22+
23+
/* PCP port numbers */
24+
enum {
25+
PCP_PORT_CLI = 5350, /* for ANNOUNCE notifications */
26+
PCP_PORT_SRV = 5351,
27+
};
28+
29+
/** PCP Protocol sizes */
30+
enum {
31+
PCP_HDR_SZ = 24,
32+
PCP_NONCE_SZ = 12,
33+
PCP_MAP_SZ = 36,
34+
PCP_PEER_SZ = 56,
35+
36+
PCP_MIN_PACKET = 24,
37+
PCP_MAX_PACKET = 1100
38+
};
39+
40+
enum pcp_opcode {
41+
PCP_ANNOUNCE = 0,
42+
PCP_MAP = 1,
43+
PCP_PEER = 2,
44+
};
45+
46+
enum pcp_result {
47+
PCP_SUCCESS = 0,
48+
PCP_UNSUPP_VERSION = 1,
49+
PCP_NOT_AUTHORIZED = 2,
50+
PCP_MALFORMED_REQUEST = 3,
51+
PCP_UNSUPP_OPCODE = 4,
52+
PCP_UNSUPP_OPTION = 5,
53+
PCP_MALFORMED_OPTION = 6,
54+
PCP_NETWORK_FAILURE = 7,
55+
PCP_NO_RESOURCES = 8,
56+
PCP_UNSUPP_PROTOCOL = 9,
57+
PCP_USER_EX_QUOTA = 10,
58+
PCP_CANNOT_PROVIDE_EXTERNAL = 11,
59+
PCP_ADDRESS_MISMATCH = 12,
60+
PCP_EXCESSIVE_REMOTE_PEERS = 13,
61+
PCP_UNSUPP_FAMILY = 14 /*draft-cheshire-pcp-unsupp-family*/
62+
};
63+
64+
enum pcp_option_code {
65+
PCP_OPTION_THIRD_PARTY = 1,
66+
PCP_OPTION_PREFER_FAILURE = 2,
67+
PCP_OPTION_FILTER = 3,
68+
PCP_OPTION_DESCRIPTION = 4, /* XXX: update with IANA code */
69+
};
70+
71+
/* forward declarations */
72+
struct udp_sock;
73+
74+
/** Defines a PCP option */
75+
struct pcp_option {
76+
struct le le;
77+
enum pcp_option_code code;
78+
union {
79+
struct sa third_party; /* Internal IP-address */
80+
struct pcp_option_filter {
81+
uint8_t prefix_length;
82+
struct sa remote_peer;
83+
} filter;
84+
char *description;
85+
} u;
86+
};
87+
88+
/**
89+
* Defines a complete and decoded PCP request/response.
90+
*
91+
* A PCP message consist of a header, and optional payload and options:
92+
*
93+
* [ Header ]
94+
* ( Opcode Payload )
95+
* ( PCP Options )
96+
*
97+
*/
98+
struct pcp_msg {
99+
100+
/** PCP Common Header */
101+
struct pcp_hdr {
102+
uint8_t version; /**< PCP Protocol version 2 */
103+
unsigned resp:1; /**< R-bit; 0=Request, 1=Response */
104+
uint8_t opcode; /**< A 7-bit opcode */
105+
uint32_t lifetime; /**< Lifetime in [seconds] */
106+
107+
/* request: */
108+
struct sa cli_addr; /**< Client's IP Address (SA_ADDR) */
109+
110+
/* response: */
111+
enum pcp_result result; /**< Result code for this response */
112+
uint32_t epoch; /**< Server's Epoch Time [seconds] */
113+
} hdr;
114+
115+
/** PCP Opcode-specific payload */
116+
union pcp_payload {
117+
struct pcp_map {
118+
uint8_t nonce[PCP_NONCE_SZ]; /**< Mapping Nonce */
119+
uint8_t proto; /**< IANA protocol */
120+
uint16_t int_port; /**< Internal Port */
121+
struct sa ext_addr; /**< External Address */
122+
} map;
123+
struct pcp_peer {
124+
uint8_t nonce[PCP_NONCE_SZ];
125+
uint8_t proto;
126+
uint16_t int_port;
127+
struct sa ext_addr;
128+
struct sa remote_addr;
129+
} peer;
130+
} pld;
131+
132+
/** List of PCP Options (struct pcp_option) */
133+
struct list optionl;
134+
};
135+
136+
/** PCP request configuration */
137+
struct pcp_conf {
138+
uint32_t irt; /**< Initial retransmission time [seconds] */
139+
uint32_t mrc; /**< Maximum retransmission count */
140+
uint32_t mrt; /**< Maximum retransmission time [seconds] */
141+
uint32_t mrd; /**< Maximum retransmission duration [seconds] */
142+
};
143+
144+
145+
/* request */
146+
147+
struct pcp_request;
148+
149+
typedef void (pcp_resp_h)(int err, const struct pcp_msg *msg, void *arg);
150+
151+
int pcp_request(struct pcp_request **reqp, const struct pcp_conf *conf,
152+
const struct sa *pcp_server, enum pcp_opcode opcode,
153+
uint32_t lifetime, const void *payload,
154+
pcp_resp_h *resph, void *arg, uint32_t optionc, ...);
155+
void pcp_force_refresh(struct pcp_request *req);
156+
157+
158+
/* reply */
159+
160+
int pcp_reply(struct udp_sock *us, const struct sa *dst, struct mbuf *req,
161+
enum pcp_opcode opcode, enum pcp_result result,
162+
uint32_t lifetime, uint32_t epoch_time, const void *payload);
163+
164+
165+
/* msg */
166+
167+
typedef bool (pcp_option_h)(const struct pcp_option *opt, void *arg);
168+
169+
int pcp_msg_decode(struct pcp_msg **msgp, struct mbuf *mb);
170+
int pcp_msg_printhdr(struct re_printf *pf, const struct pcp_msg *msg);
171+
int pcp_msg_print(struct re_printf *pf, const struct pcp_msg *msg);
172+
struct pcp_option *pcp_msg_option(const struct pcp_msg *msg,
173+
enum pcp_option_code code);
174+
struct pcp_option *pcp_msg_option_apply(const struct pcp_msg *msg,
175+
pcp_option_h *h, void *arg);
176+
const void *pcp_msg_payload(const struct pcp_msg *msg);
177+
178+
179+
/* option */
180+
181+
int pcp_option_encode(struct mbuf *mb, enum pcp_option_code code,
182+
const void *v);
183+
int pcp_option_decode(struct pcp_option **optp, struct mbuf *mb);
184+
int pcp_option_print(struct re_printf *pf, const struct pcp_option *opt);
185+
186+
187+
/* encode */
188+
189+
int pcp_msg_req_vencode(struct mbuf *mb, enum pcp_opcode opcode,
190+
uint32_t lifetime, const struct sa *cli_addr,
191+
const void *payload, uint32_t optionc, va_list ap);
192+
int pcp_msg_req_encode(struct mbuf *mb, enum pcp_opcode opcode,
193+
uint32_t lifetime, const struct sa *cli_addr,
194+
const void *payload, uint32_t optionc, ...);
195+
196+
197+
/* pcp */
198+
199+
int pcp_ipaddr_encode(struct mbuf *mb, const struct sa *sa);
200+
int pcp_ipaddr_decode(struct mbuf *mb, struct sa *sa);
201+
const char *pcp_result_name(enum pcp_result result);
202+
const char *pcp_opcode_name(enum pcp_opcode opcode);
203+
const char *pcp_proto_name(int proto);

include/rew.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ extern "C" {
1212
#endif
1313

1414

15+
#include "re_pcp.h"
1516
#include "re_shim.h"
1617
#include "re_trice.h"
1718

src/pcp/README

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
PCP README:
2+
----------
3+
4+
Port Control Protocol (PCP) as of RFC 6887
5+
6+
7+
8+
9+
other PCP implementations:
10+
11+
https://github.com/libpcp/pcp
12+
13+

src/pcp/mod.mk

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#
2+
# mod.mk
3+
#
4+
# Copyright (C) 2010 - 2016 Creytiv.com
5+
#
6+
7+
SRCS += pcp/msg.c
8+
SRCS += pcp/option.c
9+
SRCS += pcp/payload.c
10+
SRCS += pcp/pcp.c
11+
SRCS += pcp/reply.c
12+
SRCS += pcp/request.c

0 commit comments

Comments
 (0)