Dont read/write PCP messages as C struct to remove dependency to the "pack" feature.
structs are left (commented out) in pcp_msg_struct.h for information
This commit is contained in:
parent
a6b947e0ca
commit
3d8986b646
|
@ -143,6 +143,7 @@ typedef enum pcp_options {
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
/* PCP common request header*/
|
/* PCP common request header*/
|
||||||
|
#if 0
|
||||||
typedef struct pcp_request {
|
typedef struct pcp_request {
|
||||||
uint8_t ver;
|
uint8_t ver;
|
||||||
uint8_t r_opcode;
|
uint8_t r_opcode;
|
||||||
|
@ -152,8 +153,11 @@ typedef struct pcp_request {
|
||||||
by the ipv4 mapped ipv6 */
|
by the ipv4 mapped ipv6 */
|
||||||
uint8_t next_data[0];
|
uint8_t next_data[0];
|
||||||
} pcp_request_t;
|
} pcp_request_t;
|
||||||
|
#endif
|
||||||
|
#define PCP_COMMON_REQUEST_SIZE (24)
|
||||||
|
|
||||||
/* PCP common response header*/
|
/* PCP common response header*/
|
||||||
|
#if 0
|
||||||
typedef struct pcp_response {
|
typedef struct pcp_response {
|
||||||
uint8_t ver;
|
uint8_t ver;
|
||||||
uint8_t r_opcode; /* R indicates Request (0) or Response (1)
|
uint8_t r_opcode; /* R indicates Request (0) or Response (1)
|
||||||
|
@ -166,16 +170,22 @@ typedef struct pcp_response {
|
||||||
uint32_t reserved1[3];/* For requests that were successfully parsed this must be sent as 0 */
|
uint32_t reserved1[3];/* For requests that were successfully parsed this must be sent as 0 */
|
||||||
uint8_t next_data[0];
|
uint8_t next_data[0];
|
||||||
} pcp_response_t;
|
} pcp_response_t;
|
||||||
|
#endif
|
||||||
|
#define PCP_COMMON_RESPONSE_SIZE (24)
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
typedef struct pcp_options_hdr {
|
typedef struct pcp_options_hdr {
|
||||||
uint8_t code; /* Most significant bit indicates if this option is mandatory (0) or optional (1) */
|
uint8_t code; /* Most significant bit indicates if this option is mandatory (0) or optional (1) */
|
||||||
uint8_t reserved; /* MUST be set to 0 on transmission and MUST be ignored on reception */
|
uint8_t reserved; /* MUST be set to 0 on transmission and MUST be ignored on reception */
|
||||||
uint16_t len; /* indicates the length of the enclosed data in octets (see RFC) */
|
uint16_t len; /* indicates the length of the enclosed data in octets (see RFC) */
|
||||||
uint8_t next_data[0]; /* */
|
uint8_t next_data[0]; /* */
|
||||||
} pcp_options_hdr_t;
|
} pcp_options_hdr_t;
|
||||||
|
#endif
|
||||||
|
#define PCP_OPTION_HDR_SIZE (4)
|
||||||
|
|
||||||
/* same for both request and response */
|
/* same for both request and response */
|
||||||
|
#if 0
|
||||||
typedef struct pcp_map_v2 {
|
typedef struct pcp_map_v2 {
|
||||||
uint32_t nonce[3];
|
uint32_t nonce[3];
|
||||||
uint8_t protocol; /* 6 = TCP, 17 = UDP, 0 = 'all protocols' */
|
uint8_t protocol; /* 6 = TCP, 17 = UDP, 0 = 'all protocols' */
|
||||||
|
@ -186,7 +196,10 @@ typedef struct pcp_map_v2 {
|
||||||
* ipv4 will be represented by the ipv4 mapped ipv6 */
|
* ipv4 will be represented by the ipv4 mapped ipv6 */
|
||||||
uint8_t next_data[0];
|
uint8_t next_data[0];
|
||||||
} pcp_map_v2_t;
|
} pcp_map_v2_t;
|
||||||
|
#endif
|
||||||
|
#define PCP_MAP_V2_SIZE (36)
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* same for both request and response */
|
/* same for both request and response */
|
||||||
typedef struct pcp_map_v1 {
|
typedef struct pcp_map_v1 {
|
||||||
uint8_t protocol;
|
uint8_t protocol;
|
||||||
|
@ -197,8 +210,11 @@ typedef struct pcp_map_v1 {
|
||||||
by the ipv4 mapped ipv6 */
|
by the ipv4 mapped ipv6 */
|
||||||
uint8_t next_data[0];
|
uint8_t next_data[0];
|
||||||
} pcp_map_v1_t;
|
} pcp_map_v1_t;
|
||||||
|
#endif
|
||||||
|
#define PCP_MAP_V1_SIZE (24)
|
||||||
|
|
||||||
/* same for both request and response */
|
/* same for both request and response */
|
||||||
|
#if 0
|
||||||
typedef struct pcp_peer_v1 {
|
typedef struct pcp_peer_v1 {
|
||||||
uint8_t protocol;
|
uint8_t protocol;
|
||||||
uint8_t reserved[3];
|
uint8_t reserved[3];
|
||||||
|
@ -211,8 +227,11 @@ typedef struct pcp_peer_v1 {
|
||||||
struct in6_addr peer_ip;
|
struct in6_addr peer_ip;
|
||||||
uint8_t next_data[0];
|
uint8_t next_data[0];
|
||||||
} pcp_peer_v1_t;
|
} pcp_peer_v1_t;
|
||||||
|
#endif
|
||||||
|
#define PCP_PEER_V1_SIZE (44)
|
||||||
|
|
||||||
/* same for both request and response */
|
/* same for both request and response */
|
||||||
|
#if 0
|
||||||
typedef struct pcp_peer_v2 {
|
typedef struct pcp_peer_v2 {
|
||||||
uint32_t nonce[3];
|
uint32_t nonce[3];
|
||||||
uint8_t protocol;
|
uint8_t protocol;
|
||||||
|
@ -226,30 +245,41 @@ typedef struct pcp_peer_v2 {
|
||||||
struct in6_addr peer_ip;
|
struct in6_addr peer_ip;
|
||||||
uint8_t next_data[0];
|
uint8_t next_data[0];
|
||||||
} pcp_peer_v2_t;
|
} pcp_peer_v2_t;
|
||||||
|
#endif
|
||||||
|
#define PCP_PEER_V2_SIZE (56)
|
||||||
|
|
||||||
#ifdef PCP_SADSCP
|
#ifdef PCP_SADSCP
|
||||||
|
#if 0
|
||||||
typedef struct pcp_sadscp_req {
|
typedef struct pcp_sadscp_req {
|
||||||
uint32_t nonce[3];
|
uint32_t nonce[3];
|
||||||
uint8_t tolerance_fields;
|
uint8_t tolerance_fields;
|
||||||
uint8_t app_name_length;
|
uint8_t app_name_length;
|
||||||
char app_name[0];
|
char app_name[0];
|
||||||
} pcp_sadscp_req_t;
|
} pcp_sadscp_req_t;
|
||||||
|
#endif
|
||||||
|
#define PCP_SADSCP_REQ_SIZE (14)
|
||||||
|
|
||||||
|
#if 0
|
||||||
typedef struct pcp_sadscp_resp {
|
typedef struct pcp_sadscp_resp {
|
||||||
uint32_t nonce[3];
|
uint32_t nonce[3];
|
||||||
#define PCP_SADSCP_MASK ((1<<6)-1)
|
|
||||||
uint8_t a_r_dscp_value;
|
uint8_t a_r_dscp_value;
|
||||||
uint8_t reserved[3];
|
uint8_t reserved[3];
|
||||||
} pcp_sadscp_resp_t;
|
} pcp_sadscp_resp_t;
|
||||||
#endif
|
#endif
|
||||||
|
#define PCP_SADSCP_MASK ((1<<6)-1)
|
||||||
|
#endif /* PCP_SADSCP */
|
||||||
|
|
||||||
|
#if 0
|
||||||
typedef struct pcp_prefer_fail_option {
|
typedef struct pcp_prefer_fail_option {
|
||||||
uint8_t option;
|
uint8_t option;
|
||||||
uint8_t reserved;
|
uint8_t reserved;
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
uint8_t next_data[0];
|
uint8_t next_data[0];
|
||||||
} pcp_prefer_fail_option_t;
|
} pcp_prefer_fail_option_t;
|
||||||
|
#endif
|
||||||
|
#define PCP_PREFER_FAIL_OPTION_SIZE (4)
|
||||||
|
|
||||||
|
#if 0
|
||||||
typedef struct pcp_3rd_party_option{
|
typedef struct pcp_3rd_party_option{
|
||||||
uint8_t option;
|
uint8_t option;
|
||||||
uint8_t reserved;
|
uint8_t reserved;
|
||||||
|
@ -257,22 +287,28 @@ typedef struct pcp_3rd_party_option{
|
||||||
struct in6_addr ip;
|
struct in6_addr ip;
|
||||||
uint8_t next_data[0];
|
uint8_t next_data[0];
|
||||||
} pcp_3rd_party_option_t;
|
} pcp_3rd_party_option_t;
|
||||||
|
#endif
|
||||||
|
#define PCP_3RD_PARTY_OPTION_SIZE (20)
|
||||||
|
|
||||||
#ifdef PCP_FLOWP
|
#ifdef PCP_FLOWP
|
||||||
|
#if 0
|
||||||
typedef struct pcp_flow_priority_option{
|
typedef struct pcp_flow_priority_option{
|
||||||
uint8_t option;
|
uint8_t option;
|
||||||
uint8_t reserved;
|
uint8_t reserved;
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
uint8_t dscp_up;
|
uint8_t dscp_up;
|
||||||
uint8_t dscp_down;
|
uint8_t dscp_down;
|
||||||
#define PCP_DSCP_MASK ((1<<6)-1)
|
|
||||||
uint8_t reserved2;
|
uint8_t reserved2;
|
||||||
/* most significant bit is used for response */
|
/* most significant bit is used for response */
|
||||||
uint8_t response_bit;
|
uint8_t response_bit;
|
||||||
uint8_t next_data[0];
|
uint8_t next_data[0];
|
||||||
} pcp_flow_priority_option_t;
|
} pcp_flow_priority_option_t;
|
||||||
#endif
|
#endif
|
||||||
|
#define PCP_DSCP_MASK ((1<<6)-1)
|
||||||
|
#define PCP_FLOW_PRIORITY_OPTION_SIZE (8)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
typedef struct pcp_filter_option {
|
typedef struct pcp_filter_option {
|
||||||
uint8_t option;
|
uint8_t option;
|
||||||
uint8_t reserved1;
|
uint8_t reserved1;
|
||||||
|
@ -282,6 +318,8 @@ typedef struct pcp_filter_option {
|
||||||
uint16_t peer_port;
|
uint16_t peer_port;
|
||||||
struct in6_addr peer_ip;
|
struct in6_addr peer_ip;
|
||||||
}pcp_filter_option_t;
|
}pcp_filter_option_t;
|
||||||
|
#endif
|
||||||
|
#define PCP_FILTER_OPTION_SIZE (24)
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
|
|
@ -207,16 +207,16 @@ int get_dscp_value(pcp_info_t *pcp_msg_info) {
|
||||||
* result code is assigned to pcp_msg_info->result_code to indicate
|
* result code is assigned to pcp_msg_info->result_code to indicate
|
||||||
* what kind of error occurred
|
* what kind of error occurred
|
||||||
*/
|
*/
|
||||||
static int parseCommonRequestHeader(const pcp_request_t *common_req, pcp_info_t *pcp_msg_info)
|
static int parseCommonRequestHeader(const uint8_t *common_req, pcp_info_t *pcp_msg_info)
|
||||||
{
|
{
|
||||||
pcp_msg_info->version = common_req->ver ;
|
pcp_msg_info->version = common_req[0] ;
|
||||||
pcp_msg_info->opcode = common_req->r_opcode & 0x7f;
|
pcp_msg_info->opcode = common_req[1] & 0x7f;
|
||||||
pcp_msg_info->lifetime = ntohl(common_req->req_lifetime);
|
pcp_msg_info->lifetime = READNU32(common_req + 4);
|
||||||
pcp_msg_info->int_ip = &common_req->ip;
|
pcp_msg_info->int_ip = (struct in6_addr *)(common_req + 8);
|
||||||
pcp_msg_info->mapped_ip = &common_req->ip;
|
pcp_msg_info->mapped_ip = (struct in6_addr *)(common_req + 8);
|
||||||
|
|
||||||
|
|
||||||
if ( (common_req->ver > this_server_info.server_version) ) {
|
if ( (pcp_msg_info->version > this_server_info.server_version) ) {
|
||||||
pcp_msg_info->result_code = PCP_ERR_UNSUPP_VERSION;
|
pcp_msg_info->result_code = PCP_ERR_UNSUPP_VERSION;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -233,40 +233,40 @@ static int parseCommonRequestHeader(const pcp_request_t *common_req, pcp_info_t
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static void printMAPOpcodeVersion1(const pcp_map_v1_t *map_buf)
|
static void printMAPOpcodeVersion1(const uint8_t *buf)
|
||||||
{
|
{
|
||||||
char map_addr[INET6_ADDRSTRLEN];
|
char map_addr[INET6_ADDRSTRLEN];
|
||||||
syslog(LOG_DEBUG, "PCP MAP: v1 Opcode specific information. \n");
|
syslog(LOG_DEBUG, "PCP MAP: v1 Opcode specific information. \n");
|
||||||
syslog(LOG_DEBUG, "MAP protocol: \t\t %d\n",map_buf->protocol );
|
syslog(LOG_DEBUG, "MAP protocol: \t\t %d\n", (int)buf[0] );
|
||||||
syslog(LOG_DEBUG, "MAP int port: \t\t %d\n", ntohs(map_buf->int_port) );
|
syslog(LOG_DEBUG, "MAP int port: \t\t %d\n", (int)READNU16(buf+4));
|
||||||
syslog(LOG_DEBUG, "MAP ext port: \t\t %d\n", ntohs(map_buf->ext_port) );
|
syslog(LOG_DEBUG, "MAP ext port: \t\t %d\n", (int)READNU16(buf+6));
|
||||||
syslog(LOG_DEBUG, "MAP Ext IP: \t\t %s\n", inet_ntop(AF_INET6,
|
syslog(LOG_DEBUG, "MAP Ext IP: \t\t %s\n", inet_ntop(AF_INET6,
|
||||||
&map_buf->ext_ip, map_addr, INET6_ADDRSTRLEN));
|
buf+8, map_addr, INET6_ADDRSTRLEN));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printMAPOpcodeVersion2(const pcp_map_v2_t *map_buf)
|
static void printMAPOpcodeVersion2(const uint8_t *buf)
|
||||||
{
|
{
|
||||||
char map_addr[INET6_ADDRSTRLEN];
|
char map_addr[INET6_ADDRSTRLEN];
|
||||||
syslog(LOG_DEBUG, "PCP MAP: v2 Opcode specific information.");
|
syslog(LOG_DEBUG, "PCP MAP: v2 Opcode specific information.");
|
||||||
syslog(LOG_DEBUG, "MAP nonce: \t%08x%08x%08x",
|
syslog(LOG_DEBUG, "MAP nonce: \t%08x%08x%08x",
|
||||||
map_buf->nonce[0], map_buf->nonce[1], map_buf->nonce[2]);
|
READNU32(buf), READNU32(buf+4), READNU32(buf+8));
|
||||||
syslog(LOG_DEBUG, "MAP protocol:\t%d", map_buf->protocol);
|
syslog(LOG_DEBUG, "MAP protocol:\t%d", (int)buf[12]);
|
||||||
syslog(LOG_DEBUG, "MAP int port:\t%d", ntohs(map_buf->int_port));
|
syslog(LOG_DEBUG, "MAP int port:\t%d", (int)READNU16(buf+16));
|
||||||
syslog(LOG_DEBUG, "MAP ext port:\t%d", ntohs(map_buf->ext_port));
|
syslog(LOG_DEBUG, "MAP ext port:\t%d", (int)READNU16(buf+18));
|
||||||
syslog(LOG_DEBUG, "MAP Ext IP: \t%s", inet_ntop(AF_INET6,
|
syslog(LOG_DEBUG, "MAP Ext IP: \t%s", inet_ntop(AF_INET6,
|
||||||
&map_buf->ext_ip, map_addr, INET6_ADDRSTRLEN));
|
buf+20, map_addr, INET6_ADDRSTRLEN));
|
||||||
}
|
}
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
static int parsePCPMAP_version1(const pcp_map_v1_t *map_v1,
|
static int parsePCPMAP_version1(const uint8_t *map_v1,
|
||||||
pcp_info_t *pcp_msg_info)
|
pcp_info_t *pcp_msg_info)
|
||||||
{
|
{
|
||||||
pcp_msg_info->is_map_op = 1;
|
pcp_msg_info->is_map_op = 1;
|
||||||
pcp_msg_info->protocol = map_v1->protocol;
|
pcp_msg_info->protocol = map_v1[0];
|
||||||
pcp_msg_info->int_port = ntohs(map_v1->int_port);
|
pcp_msg_info->int_port = READNU16(map_v1 + 4);
|
||||||
pcp_msg_info->ext_port = ntohs(map_v1->ext_port);
|
pcp_msg_info->ext_port = READNU16(map_v1 + 6);
|
||||||
|
|
||||||
pcp_msg_info->ext_ip = &(map_v1->ext_ip);
|
pcp_msg_info->ext_ip = (struct in6_addr *)(map_v1 + 8);
|
||||||
|
|
||||||
if (pcp_msg_info->protocol == 0 && pcp_msg_info->int_port != 0) {
|
if (pcp_msg_info->protocol == 0 && pcp_msg_info->int_port != 0) {
|
||||||
syslog(LOG_ERR, "PCP MAP: Protocol was ZERO, but internal port has non-ZERO value.");
|
syslog(LOG_ERR, "PCP MAP: Protocol was ZERO, but internal port has non-ZERO value.");
|
||||||
|
@ -276,16 +276,16 @@ static int parsePCPMAP_version1(const pcp_map_v1_t *map_v1,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parsePCPMAP_version2(const pcp_map_v2_t *map_v2,
|
static int parsePCPMAP_version2(const uint8_t *map_v2,
|
||||||
pcp_info_t *pcp_msg_info)
|
pcp_info_t *pcp_msg_info)
|
||||||
{
|
{
|
||||||
pcp_msg_info->is_map_op = 1;
|
pcp_msg_info->is_map_op = 1;
|
||||||
memcpy(pcp_msg_info->nonce, map_v2->nonce, 12);
|
memcpy(pcp_msg_info->nonce, map_v2, 12);
|
||||||
pcp_msg_info->protocol = map_v2->protocol;
|
pcp_msg_info->protocol = map_v2[12];
|
||||||
pcp_msg_info->int_port = ntohs(map_v2->int_port);
|
pcp_msg_info->int_port = READNU16(map_v2 + 16);
|
||||||
pcp_msg_info->ext_port = ntohs(map_v2->ext_port);
|
pcp_msg_info->ext_port = READNU16(map_v2 + 18);
|
||||||
|
|
||||||
pcp_msg_info->ext_ip = &(map_v2->ext_ip);
|
pcp_msg_info->ext_ip = (struct in6_addr *)(map_v2 + 20);
|
||||||
|
|
||||||
if (pcp_msg_info->protocol == 0 && pcp_msg_info->int_port !=0 ) {
|
if (pcp_msg_info->protocol == 0 && pcp_msg_info->int_port !=0 ) {
|
||||||
syslog(LOG_ERR, "PCP MAP: Protocol was ZERO, but internal port has non-ZERO value.");
|
syslog(LOG_ERR, "PCP MAP: Protocol was ZERO, but internal port has non-ZERO value.");
|
||||||
|
@ -298,37 +298,37 @@ static int parsePCPMAP_version2(const pcp_map_v2_t *map_v2,
|
||||||
|
|
||||||
#ifdef PCP_PEER
|
#ifdef PCP_PEER
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static void printPEEROpcodeVersion1(pcp_peer_v1_t *peer_buf)
|
static void printPEEROpcodeVersion1(const uint8_t *buf)
|
||||||
{
|
{
|
||||||
char ext_addr[INET6_ADDRSTRLEN];
|
char ext_addr[INET6_ADDRSTRLEN];
|
||||||
char peer_addr[INET6_ADDRSTRLEN];
|
char peer_addr[INET6_ADDRSTRLEN];
|
||||||
syslog(LOG_DEBUG, "PCP PEER: v1 Opcode specific information. \n");
|
syslog(LOG_DEBUG, "PCP PEER: v1 Opcode specific information. \n");
|
||||||
syslog(LOG_DEBUG, "Protocol: \t\t %d\n",peer_buf->protocol );
|
syslog(LOG_DEBUG, "Protocol: \t\t %d\n", (int)buf[0]);
|
||||||
syslog(LOG_DEBUG, "Internal port: \t\t %d\n", ntohs(peer_buf->int_port) );
|
syslog(LOG_DEBUG, "Internal port: \t\t %d\n", READNU16(buf + 4));
|
||||||
syslog(LOG_DEBUG, "External IP: \t\t %s\n", inet_ntop(AF_INET6, &peer_buf->ext_ip,
|
syslog(LOG_DEBUG, "External IP: \t\t %s\n", inet_ntop(AF_INET6, buf + 8,
|
||||||
ext_addr,INET6_ADDRSTRLEN));
|
ext_addr,INET6_ADDRSTRLEN));
|
||||||
syslog(LOG_DEBUG, "External port port: \t\t %d\n", ntohs(peer_buf->ext_port) );
|
syslog(LOG_DEBUG, "External port port: \t\t %d\n", READNU16(buf + 6));
|
||||||
syslog(LOG_DEBUG, "PEER IP: \t\t %s\n", inet_ntop(AF_INET6, &peer_buf->peer_ip,
|
syslog(LOG_DEBUG, "PEER IP: \t\t %s\n", inet_ntop(AF_INET6, buf + 28,
|
||||||
peer_addr,INET6_ADDRSTRLEN));
|
peer_addr,INET6_ADDRSTRLEN));
|
||||||
syslog(LOG_DEBUG, "PEER port port: \t\t %d\n", ntohs(peer_buf->peer_port) );
|
syslog(LOG_DEBUG, "PEER port port: \t\t %d\n", READNU16(buf + 24));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printPEEROpcodeVersion2(pcp_peer_v2_t *peer_buf)
|
static void printPEEROpcodeVersion2(const uint8_t *buf)
|
||||||
{
|
{
|
||||||
char ext_addr[INET6_ADDRSTRLEN];
|
char ext_addr[INET6_ADDRSTRLEN];
|
||||||
char peer_addr[INET6_ADDRSTRLEN];
|
char peer_addr[INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
syslog(LOG_DEBUG, "PCP PEER: v2 Opcode specific information.");
|
syslog(LOG_DEBUG, "PCP PEER: v2 Opcode specific information.");
|
||||||
syslog(LOG_DEBUG, "nonce: \t%08x%08x%08x",
|
syslog(LOG_DEBUG, "nonce: \t%08x%08x%08x",
|
||||||
peer_buf->nonce[0], peer_buf->nonce[1], peer_buf->nonce[2]);
|
READNU32(buf), READNU32(buf+4), READNU32(buf+8));
|
||||||
syslog(LOG_DEBUG, "Protocol: \t%d",peer_buf->protocol );
|
syslog(LOG_DEBUG, "Protocol: \t%d", buf[12]);
|
||||||
syslog(LOG_DEBUG, "Internal port:\t%d", ntohs(peer_buf->int_port) );
|
syslog(LOG_DEBUG, "Internal port:\t%d", READNU16(buf + 16));
|
||||||
syslog(LOG_DEBUG, "External IP: \t%s", inet_ntop(AF_INET6, &peer_buf->ext_ip,
|
syslog(LOG_DEBUG, "External IP: \t%s", inet_ntop(AF_INET6, buf + 20,
|
||||||
ext_addr, INET6_ADDRSTRLEN));
|
ext_addr, INET6_ADDRSTRLEN));
|
||||||
syslog(LOG_DEBUG, "External port:\t%d", ntohs(peer_buf->ext_port) );
|
syslog(LOG_DEBUG, "External port:\t%d", READNU16(buf + 18));
|
||||||
syslog(LOG_DEBUG, "PEER IP: \t%s", inet_ntop(AF_INET6, &peer_buf->peer_ip,
|
syslog(LOG_DEBUG, "PEER IP: \t%s", inet_ntop(AF_INET6, buf + 40,
|
||||||
peer_addr, INET6_ADDRSTRLEN));
|
peer_addr, INET6_ADDRSTRLEN));
|
||||||
syslog(LOG_DEBUG, "PEER port: \t%d", ntohs(peer_buf->peer_port) );
|
syslog(LOG_DEBUG, "PEER port: \t%d", READNU16(buf + 36));
|
||||||
}
|
}
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
@ -336,17 +336,17 @@ static void printPEEROpcodeVersion2(pcp_peer_v2_t *peer_buf)
|
||||||
* Function extracting information from peer_buf to pcp_msg_info
|
* Function extracting information from peer_buf to pcp_msg_info
|
||||||
* @return : when no problem occurred 0 is returned, 1 otherwise
|
* @return : when no problem occurred 0 is returned, 1 otherwise
|
||||||
*/
|
*/
|
||||||
static int parsePCPPEER_version1(pcp_peer_v1_t *peer_buf, \
|
static int parsePCPPEER_version1(const uint8_t *buf,
|
||||||
pcp_info_t *pcp_msg_info)
|
pcp_info_t *pcp_msg_info)
|
||||||
{
|
{
|
||||||
pcp_msg_info->is_peer_op = 1;
|
pcp_msg_info->is_peer_op = 1;
|
||||||
pcp_msg_info->protocol = peer_buf->protocol;
|
pcp_msg_info->protocol = buf[0];
|
||||||
pcp_msg_info->int_port = ntohs(peer_buf->int_port);
|
pcp_msg_info->int_port = READNU16(buf + 4);
|
||||||
pcp_msg_info->ext_port = ntohs(peer_buf->ext_port);
|
pcp_msg_info->ext_port = READNU16(buf + 6);
|
||||||
pcp_msg_info->peer_port = ntohs(peer_buf->peer_port);
|
pcp_msg_info->peer_port = READNU16(buf + 24);
|
||||||
|
|
||||||
pcp_msg_info->ext_ip = &peer_buf->ext_ip;
|
pcp_msg_info->ext_ip = (struct in6_addr *)(buf + 8);
|
||||||
pcp_msg_info->peer_ip = &peer_buf->peer_ip;
|
pcp_msg_info->peer_ip = (struct in6_addr *)(buf + 28);
|
||||||
|
|
||||||
if (pcp_msg_info->protocol == 0 && pcp_msg_info->int_port !=0) {
|
if (pcp_msg_info->protocol == 0 && pcp_msg_info->int_port !=0) {
|
||||||
syslog(LOG_ERR, "PCP PEER: protocol was ZERO, but internal port has non-ZERO value.");
|
syslog(LOG_ERR, "PCP PEER: protocol was ZERO, but internal port has non-ZERO value.");
|
||||||
|
@ -360,18 +360,17 @@ static int parsePCPPEER_version1(pcp_peer_v1_t *peer_buf, \
|
||||||
* Function extracting information from peer_buf to pcp_msg_info
|
* Function extracting information from peer_buf to pcp_msg_info
|
||||||
* @return : when no problem occurred 0 is returned, 1 otherwise
|
* @return : when no problem occurred 0 is returned, 1 otherwise
|
||||||
*/
|
*/
|
||||||
static int parsePCPPEER_version2(pcp_peer_v2_t *peer_buf, \
|
static int parsePCPPEER_version2(const uint8_t *buf, pcp_info_t *pcp_msg_info)
|
||||||
pcp_info_t *pcp_msg_info)
|
|
||||||
{
|
{
|
||||||
pcp_msg_info->is_peer_op = 1;
|
pcp_msg_info->is_peer_op = 1;
|
||||||
memcpy(pcp_msg_info->nonce, peer_buf->nonce, 12);
|
memcpy(pcp_msg_info->nonce, buf, 12);
|
||||||
pcp_msg_info->protocol = peer_buf->protocol;
|
pcp_msg_info->protocol = buf[12];
|
||||||
pcp_msg_info->int_port = ntohs(peer_buf->int_port);
|
pcp_msg_info->int_port = READNU16(buf + 16);
|
||||||
pcp_msg_info->ext_port = ntohs(peer_buf->ext_port);
|
pcp_msg_info->ext_port = READNU16(buf + 18);
|
||||||
pcp_msg_info->peer_port = ntohs(peer_buf->peer_port);
|
pcp_msg_info->peer_port = READNU16(buf + 36);
|
||||||
|
|
||||||
pcp_msg_info->ext_ip = &peer_buf->ext_ip;
|
pcp_msg_info->ext_ip = (struct in6_addr *)(buf + 20);
|
||||||
pcp_msg_info->peer_ip = &peer_buf->peer_ip;
|
pcp_msg_info->peer_ip = (struct in6_addr *)(buf + 40);
|
||||||
|
|
||||||
if (pcp_msg_info->protocol == 0 && pcp_msg_info->int_port != 0) {
|
if (pcp_msg_info->protocol == 0 && pcp_msg_info->int_port != 0) {
|
||||||
syslog(LOG_ERR, "PCP PEER: protocol was ZERO, but internal port has non-ZERO value.");
|
syslog(LOG_ERR, "PCP PEER: protocol was ZERO, but internal port has non-ZERO value.");
|
||||||
|
@ -384,110 +383,89 @@ static int parsePCPPEER_version2(pcp_peer_v2_t *peer_buf, \
|
||||||
|
|
||||||
#ifdef PCP_SADSCP
|
#ifdef PCP_SADSCP
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static void printSADSCPOpcode(pcp_sadscp_req_t *sadscp) {
|
static void printSADSCPOpcode(const uint8_t *buf)
|
||||||
|
{
|
||||||
unsigned char sadscp_tol;
|
unsigned char sadscp_tol;
|
||||||
sadscp_tol = sadscp->tolerance_fields;
|
sadscp_tol = buf[12]; /* tolerance_fields */
|
||||||
|
|
||||||
syslog(LOG_DEBUG, "PCP SADSCP: Opcode specific information.\n");
|
syslog(LOG_DEBUG, "PCP SADSCP: Opcode specific information.\n");
|
||||||
syslog(LOG_DEBUG, "Delay tolerance %d \n", (sadscp_tol>>6)&3);
|
syslog(LOG_DEBUG, "Delay tolerance %d \n", (sadscp_tol>>6)&3);
|
||||||
syslog(LOG_DEBUG, "Loss tolerance %d \n", (sadscp_tol>>4)&3);
|
syslog(LOG_DEBUG, "Loss tolerance %d \n", (sadscp_tol>>4)&3);
|
||||||
syslog(LOG_DEBUG, "Jitter tolerance %d \n", (sadscp_tol>>2)&3);
|
syslog(LOG_DEBUG, "Jitter tolerance %d \n", (sadscp_tol>>2)&3);
|
||||||
syslog(LOG_DEBUG, "RRR %d \n", sadscp_tol&3);
|
syslog(LOG_DEBUG, "RRR %d \n", sadscp_tol&3);
|
||||||
syslog(LOG_DEBUG, "AppName Length %d \n", sadscp->app_name_length);
|
syslog(LOG_DEBUG, "AppName Length %d \n", buf[13]);
|
||||||
if (sadscp->app_name) {
|
syslog(LOG_DEBUG, "Application name %.*s \n", buf[13], buf + 14);
|
||||||
syslog(LOG_DEBUG, "Application name %.*s \n", sadscp->app_name_length,
|
|
||||||
sadscp->app_name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif //DEBUG
|
#endif //DEBUG
|
||||||
|
|
||||||
static int parseSADSCP(pcp_sadscp_req_t *sadscp, pcp_info_t *pcp_msg_info) {
|
static int parseSADSCP(const uint8_t *buf, pcp_info_t *pcp_msg_info)
|
||||||
|
{
|
||||||
|
pcp_msg_info->delay_tolerance = (buf[12]>>6)&3;
|
||||||
|
pcp_msg_info->loss_tolerance = (buf[12]>>4)&3;
|
||||||
|
pcp_msg_info->jitter_tolerance = (buf[12]>>2)&3;
|
||||||
|
|
||||||
pcp_msg_info->delay_tolerance = (sadscp->tolerance_fields>>6)&3;
|
if (pcp_msg_info->delay_tolerance == 3 ||
|
||||||
pcp_msg_info->loss_tolerance = (sadscp->tolerance_fields>>4)&3;
|
pcp_msg_info->loss_tolerance == 3 ||
|
||||||
pcp_msg_info->jitter_tolerance = (sadscp->tolerance_fields>>2)&3;
|
pcp_msg_info->jitter_tolerance == 3 ) {
|
||||||
|
|
||||||
if (pcp_msg_info->delay_tolerance == 3 ) {
|
|
||||||
pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if ( pcp_msg_info->loss_tolerance == 3 ) {
|
|
||||||
pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if ( pcp_msg_info->jitter_tolerance == 3 ) {
|
|
||||||
pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST;
|
pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcp_msg_info->app_name = sadscp->app_name;
|
pcp_msg_info->app_name = (const char *)(buf + 14);
|
||||||
pcp_msg_info->app_name_len = sadscp->app_name_length;
|
pcp_msg_info->app_name_len = buf[13];
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* PCP_SADSCP */
|
||||||
|
|
||||||
static int parsePCPOption(void* pcp_buf, int remain, pcp_info_t *pcp_msg_info)
|
|
||||||
|
static int parsePCPOption(uint8_t* pcp_buf, int remain, pcp_info_t *pcp_msg_info)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
char third_addr[INET6_ADDRSTRLEN];
|
char third_addr[INET6_ADDRSTRLEN];
|
||||||
#endif
|
#endif /* DEBUG */
|
||||||
unsigned short option_length;
|
unsigned short option_length;
|
||||||
|
|
||||||
pcp_3rd_party_option_t* opt_3rd;
|
|
||||||
#ifdef PCP_FLOWP
|
|
||||||
pcp_flow_priority_option_t* opt_flp;
|
|
||||||
#endif
|
|
||||||
pcp_filter_option_t* opt_filter;
|
|
||||||
pcp_prefer_fail_option_t* opt_prefail;
|
|
||||||
pcp_options_hdr_t* opt_hdr;
|
|
||||||
|
|
||||||
opt_hdr = (pcp_options_hdr_t*)pcp_buf;
|
|
||||||
|
|
||||||
/* Do centralized option sanity checks here. */
|
/* Do centralized option sanity checks here. */
|
||||||
|
|
||||||
if (remain < (int)sizeof(*opt_hdr)) {
|
if (remain < (int)PCP_OPTION_HDR_SIZE) {
|
||||||
pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION;
|
pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
option_length = ntohs(opt_hdr->len) + 4;
|
option_length = READNU16(pcp_buf + 2) + 4; /* len */
|
||||||
|
|
||||||
if (remain < option_length) {
|
if (remain < option_length) {
|
||||||
pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION;
|
pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (opt_hdr->code) {
|
switch (pcp_buf[0]) { /* code */
|
||||||
|
|
||||||
case PCP_OPTION_3RD_PARTY:
|
case PCP_OPTION_3RD_PARTY:
|
||||||
|
|
||||||
opt_3rd = (pcp_3rd_party_option_t*)pcp_buf;
|
if (option_length != PCP_3RD_PARTY_OPTION_SIZE) {
|
||||||
if ( option_length != sizeof(*opt_3rd) ) {
|
|
||||||
pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION;
|
pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
syslog(LOG_DEBUG, "PCP OPTION: \t Third party\n");
|
syslog(LOG_DEBUG, "PCP OPTION: \t Third party\n");
|
||||||
syslog(LOG_DEBUG, "Third PARTY IP: \t %s\n", inet_ntop(AF_INET6,
|
syslog(LOG_DEBUG, "Third PARTY IP: \t %s\n", inet_ntop(AF_INET6,
|
||||||
&(opt_3rd->ip), third_addr, INET6_ADDRSTRLEN));
|
pcp_buf + 4, third_addr, INET6_ADDRSTRLEN));
|
||||||
#endif
|
#endif
|
||||||
if (pcp_msg_info->thirdp_ip ) {
|
if (pcp_msg_info->thirdp_ip ) {
|
||||||
syslog(LOG_ERR, "PCP: THIRD PARTY OPTION was already present. \n");
|
syslog(LOG_ERR, "PCP: THIRD PARTY OPTION was already present. \n");
|
||||||
pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION;
|
pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else {
|
||||||
else {
|
pcp_msg_info->thirdp_ip = (struct in6_addr *)(pcp_buf + 4);
|
||||||
pcp_msg_info->thirdp_ip = &opt_3rd->ip;
|
pcp_msg_info->mapped_ip = (struct in6_addr *)(pcp_buf + 4);
|
||||||
pcp_msg_info->mapped_ip = &opt_3rd->ip;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCP_OPTION_PREF_FAIL:
|
case PCP_OPTION_PREF_FAIL:
|
||||||
|
|
||||||
opt_prefail = (pcp_prefer_fail_option_t*)pcp_buf;
|
if (option_length != PCP_PREFER_FAIL_OPTION_SIZE) {
|
||||||
|
|
||||||
if ( option_length != sizeof(*opt_prefail) ) {
|
|
||||||
pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION;
|
pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -501,17 +479,14 @@ static int parsePCPOption(void* pcp_buf, int remain, pcp_info_t *pcp_msg_info)
|
||||||
if (pcp_msg_info->pfailure_present != 0 ) {
|
if (pcp_msg_info->pfailure_present != 0 ) {
|
||||||
syslog(LOG_DEBUG, "PCP: PREFER FAILURE OPTION was already present.\n");
|
syslog(LOG_DEBUG, "PCP: PREFER FAILURE OPTION was already present.\n");
|
||||||
pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION;
|
pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
pcp_msg_info->pfailure_present = 1;
|
pcp_msg_info->pfailure_present = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCP_OPTION_FILTER:
|
case PCP_OPTION_FILTER:
|
||||||
/* TODO fully implement filter */
|
/* TODO fully implement filter */
|
||||||
opt_filter = (pcp_filter_option_t*)pcp_buf;
|
if (option_length != PCP_FILTER_OPTION_SIZE) {
|
||||||
|
|
||||||
if ( option_length != sizeof(*opt_filter) ) {
|
|
||||||
pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION;
|
pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -531,28 +506,26 @@ static int parsePCPOption(void* pcp_buf, int remain, pcp_info_t *pcp_msg_info)
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
syslog(LOG_DEBUG, "PCP OPTION: \t Flow priority\n");
|
syslog(LOG_DEBUG, "PCP OPTION: \t Flow priority\n");
|
||||||
#endif
|
#endif
|
||||||
opt_flp = (pcp_flow_priority_option_t*)pcp_buf;
|
if (option_length != PCP_FLOW_PRIORITY_OPTION_SIZE) {
|
||||||
|
|
||||||
if ( option_length != sizeof (*opt_flp) ) {
|
|
||||||
syslog(LOG_ERR, "PCP: Error processing DSCP. sizeof %d and remaining %d. flow len %d \n",
|
syslog(LOG_ERR, "PCP: Error processing DSCP. sizeof %d and remaining %d. flow len %d \n",
|
||||||
(int)sizeof(pcp_flow_priority_option_t), remain, opt_flp->len);
|
PCP_FLOW_PRIORITY_OPTION_SIZE, remain, READNU16(pcp_buf + 2));
|
||||||
pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION;
|
pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
syslog(LOG_DEBUG, "DSCP UP: \t %d \n", opt_flp->dscp_up);
|
syslog(LOG_DEBUG, "DSCP UP: \t %d\n", pcp_buf[4]);
|
||||||
syslog(LOG_DEBUG, "DSCP DOWN: \t %d \n", opt_flp->dscp_down);
|
syslog(LOG_DEBUG, "DSCP DOWN: \t %d\n", pcp_buf[5]);
|
||||||
#endif
|
#endif
|
||||||
pcp_msg_info->dscp_up = opt_flp->dscp_up;
|
pcp_msg_info->dscp_up = pcp_buf[4];
|
||||||
pcp_msg_info->dscp_down = opt_flp->dscp_down;
|
pcp_msg_info->dscp_down = pcp_buf[5];
|
||||||
pcp_msg_info->flowp_present = 1;
|
pcp_msg_info->flowp_present = 1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
if (opt_hdr->code < 128) {
|
if (pcp_buf[0] < 128) {
|
||||||
syslog(LOG_ERR, "PCP: Unrecognized mandatory PCP OPTION: %d \n", opt_hdr->code);
|
syslog(LOG_ERR, "PCP: Unrecognized mandatory PCP OPTION: %d \n", (int)pcp_buf[0]);
|
||||||
/* Mandatory to understand */
|
/* Mandatory to understand */
|
||||||
pcp_msg_info->result_code = PCP_ERR_UNSUPP_OPTION;
|
pcp_msg_info->result_code = PCP_ERR_UNSUPP_OPTION;
|
||||||
remain = 0;
|
remain = 0;
|
||||||
|
@ -1224,17 +1197,8 @@ static int processPCPRequest(void * req, int req_size, pcp_info_t *pcp_msg_info)
|
||||||
{
|
{
|
||||||
int remainingSize;
|
int remainingSize;
|
||||||
|
|
||||||
const pcp_map_v1_t* map_v1;
|
/* start with PCP_SUCCESS as result code,
|
||||||
const pcp_map_v2_t* map_v2;
|
* if everything is OK value will be unchanged */
|
||||||
#ifdef PCP_PEER
|
|
||||||
pcp_peer_v1_t* peer_v1;
|
|
||||||
pcp_peer_v2_t* peer_v2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PCP_SADSCP
|
|
||||||
pcp_sadscp_req_t* sadscp;
|
|
||||||
#endif
|
|
||||||
/* start with PCP_SUCCESS as result code, if everything is OK value will be unchanged */
|
|
||||||
pcp_msg_info->result_code = PCP_SUCCESS;
|
pcp_msg_info->result_code = PCP_SUCCESS;
|
||||||
|
|
||||||
remainingSize = req_size;
|
remainingSize = req_size;
|
||||||
|
@ -1258,33 +1222,32 @@ static int processPCPRequest(void * req, int req_size, pcp_info_t *pcp_msg_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* first parse request header */
|
/* first parse request header */
|
||||||
if (parseCommonRequestHeader((pcp_request_t*)req, pcp_msg_info) ) {
|
if (parseCommonRequestHeader(req, pcp_msg_info) ) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
remainingSize -= sizeof(pcp_request_t);
|
remainingSize -= PCP_COMMON_REQUEST_SIZE;
|
||||||
req += sizeof(pcp_request_t);
|
req += PCP_COMMON_REQUEST_SIZE;
|
||||||
|
|
||||||
if (pcp_msg_info->version == 1) {
|
if (pcp_msg_info->version == 1) {
|
||||||
/* legacy PCP version 1 support */
|
/* legacy PCP version 1 support */
|
||||||
switch (pcp_msg_info->opcode) {
|
switch (pcp_msg_info->opcode) {
|
||||||
case PCP_OPCODE_MAP:
|
case PCP_OPCODE_MAP:
|
||||||
|
|
||||||
remainingSize -= sizeof(pcp_map_v1_t);
|
remainingSize -= PCP_MAP_V1_SIZE;
|
||||||
if (remainingSize < 0) {
|
if (remainingSize < 0) {
|
||||||
pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST;
|
pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST;
|
||||||
return pcp_msg_info->result_code;
|
return pcp_msg_info->result_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
map_v1 = (pcp_map_v1_t*)req;
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printMAPOpcodeVersion1(map_v1);
|
printMAPOpcodeVersion1(req);
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
if ( parsePCPMAP_version1(map_v1, pcp_msg_info) ) {
|
if ( parsePCPMAP_version1(req, pcp_msg_info) ) {
|
||||||
return pcp_msg_info->result_code;
|
return pcp_msg_info->result_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
req += sizeof(pcp_map_v1_t);
|
req += PCP_MAP_V1_SIZE;
|
||||||
|
|
||||||
parsePCPOptions(req, remainingSize, pcp_msg_info);
|
parsePCPOptions(req, remainingSize, pcp_msg_info);
|
||||||
if (ValidatePCPMsg(pcp_msg_info)) {
|
if (ValidatePCPMsg(pcp_msg_info)) {
|
||||||
|
@ -1303,21 +1266,20 @@ static int processPCPRequest(void * req, int req_size, pcp_info_t *pcp_msg_info)
|
||||||
#ifdef PCP_PEER
|
#ifdef PCP_PEER
|
||||||
case PCP_OPCODE_PEER:
|
case PCP_OPCODE_PEER:
|
||||||
|
|
||||||
remainingSize -= sizeof(pcp_peer_v1_t);
|
remainingSize -= PCP_PEER_V1_SIZE;
|
||||||
if (remainingSize < 0) {
|
if (remainingSize < 0) {
|
||||||
pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST;
|
pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST;
|
||||||
return pcp_msg_info->result_code;
|
return pcp_msg_info->result_code;
|
||||||
}
|
}
|
||||||
peer_v1 = (pcp_peer_v1_t*)req;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printPEEROpcodeVersion1(peer_v1);
|
printPEEROpcodeVersion1(req);
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
if ( parsePCPPEER_version1(peer_v1, pcp_msg_info) ) {
|
if ( parsePCPPEER_version1(req, pcp_msg_info) ) {
|
||||||
return pcp_msg_info->result_code;
|
return pcp_msg_info->result_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
req += sizeof(pcp_peer_v1_t);
|
req += PCP_PEER_V1_SIZE;
|
||||||
|
|
||||||
parsePCPOptions(req, remainingSize, pcp_msg_info);
|
parsePCPOptions(req, remainingSize, pcp_msg_info);
|
||||||
|
|
||||||
|
@ -1349,22 +1311,20 @@ static int processPCPRequest(void * req, int req_size, pcp_info_t *pcp_msg_info)
|
||||||
break;
|
break;
|
||||||
case PCP_OPCODE_MAP:
|
case PCP_OPCODE_MAP:
|
||||||
|
|
||||||
remainingSize -= sizeof(pcp_map_v2_t);
|
remainingSize -= PCP_MAP_V2_SIZE;
|
||||||
if (remainingSize < 0) {
|
if (remainingSize < 0) {
|
||||||
pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST;
|
pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST;
|
||||||
return pcp_msg_info->result_code;
|
return pcp_msg_info->result_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
map_v2 = (pcp_map_v2_t*)req;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printMAPOpcodeVersion2(map_v2);
|
printMAPOpcodeVersion2(req);
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
if (parsePCPMAP_version2(map_v2, pcp_msg_info) ) {
|
if (parsePCPMAP_version2(req, pcp_msg_info) ) {
|
||||||
return pcp_msg_info->result_code;
|
return pcp_msg_info->result_code;
|
||||||
}
|
}
|
||||||
req += sizeof(pcp_map_v2_t);
|
req += PCP_MAP_V2_SIZE;
|
||||||
|
|
||||||
parsePCPOptions(req, remainingSize, pcp_msg_info);
|
parsePCPOptions(req, remainingSize, pcp_msg_info);
|
||||||
|
|
||||||
|
@ -1384,18 +1344,17 @@ static int processPCPRequest(void * req, int req_size, pcp_info_t *pcp_msg_info)
|
||||||
#ifdef PCP_PEER
|
#ifdef PCP_PEER
|
||||||
case PCP_OPCODE_PEER:
|
case PCP_OPCODE_PEER:
|
||||||
|
|
||||||
remainingSize -= sizeof(pcp_peer_v2_t);
|
remainingSize -= PCP_PEER_V2_SIZE;
|
||||||
if (remainingSize < 0) {
|
if (remainingSize < 0) {
|
||||||
pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST;
|
pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST;
|
||||||
return pcp_msg_info->result_code;
|
return pcp_msg_info->result_code;
|
||||||
}
|
}
|
||||||
peer_v2 = (pcp_peer_v2_t*)req;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printPEEROpcodeVersion2(peer_v2);
|
printPEEROpcodeVersion2(req);
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
parsePCPPEER_version2(peer_v2, pcp_msg_info);
|
parsePCPPEER_version2(req, pcp_msg_info);
|
||||||
req += sizeof(pcp_peer_v2_t);
|
req += PCP_PEER_V2_SIZE;
|
||||||
|
|
||||||
if (pcp_msg_info->result_code != 0) {
|
if (pcp_msg_info->result_code != 0) {
|
||||||
return pcp_msg_info->result_code;
|
return pcp_msg_info->result_code;
|
||||||
|
@ -1418,25 +1377,27 @@ static int processPCPRequest(void * req, int req_size, pcp_info_t *pcp_msg_info)
|
||||||
|
|
||||||
#ifdef PCP_SADSCP
|
#ifdef PCP_SADSCP
|
||||||
case PCP_OPCODE_SADSCP:
|
case PCP_OPCODE_SADSCP:
|
||||||
remainingSize -= sizeof(pcp_sadscp_req_t);
|
remainingSize -= PCP_SADSCP_REQ_SIZE;
|
||||||
if (remainingSize < 0) {
|
if (remainingSize < 0) {
|
||||||
pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST;
|
pcp_msg_info->result_code = PCP_ERR_MALFORMED_REQUEST;
|
||||||
return pcp_msg_info->result_code;
|
return pcp_msg_info->result_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
sadscp = (pcp_sadscp_req_t*)req;
|
remainingSize -= ((uint8_t *)req)[13]; /* app_name_length */
|
||||||
req += sizeof(pcp_sadscp_req_t);
|
if (remainingSize < 0) {
|
||||||
|
|
||||||
if (sadscp->app_name_length > remainingSize) {
|
|
||||||
pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION;
|
pcp_msg_info->result_code = PCP_ERR_MALFORMED_OPTION;
|
||||||
|
return pcp_msg_info->result_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printSADSCPOpcode(sadscp);
|
printSADSCPOpcode(req);
|
||||||
#endif
|
#endif
|
||||||
if (parseSADSCP(sadscp, pcp_msg_info)) {
|
parseSADSCP(req, pcp_msg_info);
|
||||||
|
req += PCP_SADSCP_REQ_SIZE;
|
||||||
|
if (pcp_msg_info->result_code != 0) {
|
||||||
return pcp_msg_info->result_code;
|
return pcp_msg_info->result_code;
|
||||||
}
|
}
|
||||||
|
req += pcp_msg_info->app_name_len;
|
||||||
|
|
||||||
get_dscp_value(pcp_msg_info);
|
get_dscp_value(pcp_msg_info);
|
||||||
|
|
||||||
|
@ -1457,22 +1418,18 @@ static int processPCPRequest(void * req, int req_size, pcp_info_t *pcp_msg_info)
|
||||||
|
|
||||||
static void createPCPResponse(unsigned char *response, pcp_info_t *pcp_msg_info)
|
static void createPCPResponse(unsigned char *response, pcp_info_t *pcp_msg_info)
|
||||||
{
|
{
|
||||||
pcp_response_t *resp = (pcp_response_t*)response;
|
response[2] = 0; /* reserved */
|
||||||
|
memset(response + 12, 0, 12); /* reserved */
|
||||||
resp->reserved = 0;
|
|
||||||
resp->reserved1[0]=0;
|
|
||||||
resp->reserved1[1]=0;
|
|
||||||
resp->reserved1[2]=0;
|
|
||||||
if (pcp_msg_info->result_code == PCP_ERR_UNSUPP_VERSION ) {
|
if (pcp_msg_info->result_code == PCP_ERR_UNSUPP_VERSION ) {
|
||||||
/* highest supported version */
|
/* highest supported version */
|
||||||
resp->ver = this_server_info.server_version;
|
response[0] = this_server_info.server_version;
|
||||||
} else {
|
} else {
|
||||||
resp->ver = pcp_msg_info->version;
|
response[0] = pcp_msg_info->version;
|
||||||
}
|
}
|
||||||
|
|
||||||
resp->r_opcode |= 0x80;
|
response[1] |= 0x80; /* r_opcode */
|
||||||
resp->result_code = pcp_msg_info->result_code;
|
response[3] = pcp_msg_info->result_code;
|
||||||
resp->epochtime = htonl(time(NULL) - startup_time);
|
WRITENU32(response + 8, time(NULL) - startup_time); /* epochtime */
|
||||||
switch (pcp_msg_info->result_code) {
|
switch (pcp_msg_info->result_code) {
|
||||||
/*long lifetime errors*/
|
/*long lifetime errors*/
|
||||||
case PCP_ERR_UNSUPP_VERSION:
|
case PCP_ERR_UNSUPP_VERSION:
|
||||||
|
@ -1485,61 +1442,56 @@ static void createPCPResponse(unsigned char *response, pcp_info_t *pcp_msg_info)
|
||||||
case PCP_ERR_ADDRESS_MISMATCH:
|
case PCP_ERR_ADDRESS_MISMATCH:
|
||||||
case PCP_ERR_CANNOT_PROVIDE_EXTERNAL:
|
case PCP_ERR_CANNOT_PROVIDE_EXTERNAL:
|
||||||
case PCP_ERR_EXCESSIVE_REMOTE_PEERS:
|
case PCP_ERR_EXCESSIVE_REMOTE_PEERS:
|
||||||
resp->lifetime = 0;
|
WRITENU32(response + 4, 0); /* lifetime */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCP_ERR_NETWORK_FAILURE:
|
case PCP_ERR_NETWORK_FAILURE:
|
||||||
case PCP_ERR_NO_RESOURCES:
|
case PCP_ERR_NO_RESOURCES:
|
||||||
case PCP_ERR_USER_EX_QUOTA:
|
case PCP_ERR_USER_EX_QUOTA:
|
||||||
resp->lifetime = htonl(30);
|
WRITENU32(response + 4, 30); /* lifetime */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCP_SUCCESS:
|
case PCP_SUCCESS:
|
||||||
default:
|
default:
|
||||||
resp->lifetime = htonl(pcp_msg_info->lifetime);
|
WRITENU32(response + 4, pcp_msg_info->lifetime); /* lifetime */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resp->r_opcode == 0x81) { /* MAP response */
|
if (response[1] == 0x81) { /* MAP response */
|
||||||
if (resp->ver == 1 ) {
|
if (response[0] == 1) { /* version */
|
||||||
pcp_map_v1_t *mapr = (pcp_map_v1_t *)resp->next_data;
|
WRITENU16(response + PCP_COMMON_RESPONSE_SIZE + 4, pcp_msg_info->int_port);
|
||||||
mapr->ext_ip = *pcp_msg_info->ext_ip;
|
WRITENU16(response + PCP_COMMON_RESPONSE_SIZE + 6, pcp_msg_info->ext_port);
|
||||||
mapr->ext_port = htons(pcp_msg_info->ext_port);
|
memcpy(response + PCP_COMMON_RESPONSE_SIZE + 8, pcp_msg_info->ext_ip, sizeof(struct in6_addr));
|
||||||
mapr->int_port = htons(pcp_msg_info->int_port);
|
|
||||||
}
|
}
|
||||||
else if (resp->ver == 2 ) {
|
else if (response[0] == 2) {
|
||||||
pcp_map_v2_t *mapr = (pcp_map_v2_t *)resp->next_data;
|
WRITENU16(response + PCP_COMMON_RESPONSE_SIZE + 16, pcp_msg_info->int_port);
|
||||||
mapr->ext_ip = *pcp_msg_info->ext_ip;
|
WRITENU16(response + PCP_COMMON_RESPONSE_SIZE + 18, pcp_msg_info->ext_port);
|
||||||
mapr->ext_port = htons(pcp_msg_info->ext_port);
|
memcpy(response + PCP_COMMON_RESPONSE_SIZE + 20, pcp_msg_info->ext_ip, sizeof(struct in6_addr));
|
||||||
mapr->int_port = htons(pcp_msg_info->int_port);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef PCP_PEER
|
#ifdef PCP_PEER
|
||||||
else if (resp->r_opcode == 0x82) { /* PEER response */
|
else if (response[1] == 0x82) { /* PEER response */
|
||||||
if (resp->ver == 1 ){
|
if (response[0] == 1) {
|
||||||
pcp_peer_v1_t* peer_resp = (pcp_peer_v1_t*)resp->next_data;
|
WRITENU16(response + PCP_COMMON_RESPONSE_SIZE + 4, pcp_msg_info->int_port);
|
||||||
peer_resp->ext_port = htons(pcp_msg_info->ext_port);
|
WRITENU16(response + PCP_COMMON_RESPONSE_SIZE + 6, pcp_msg_info->ext_port);
|
||||||
peer_resp->int_port = htons(pcp_msg_info->int_port);
|
WRITENU16(response + PCP_COMMON_RESPONSE_SIZE + 24, pcp_msg_info->peer_port);
|
||||||
peer_resp->peer_port = htons(pcp_msg_info->peer_port);
|
memcpy(response + PCP_COMMON_RESPONSE_SIZE + 8, pcp_msg_info->ext_ip, sizeof(struct in6_addr));
|
||||||
peer_resp->ext_ip = *pcp_msg_info->ext_ip;
|
|
||||||
}
|
}
|
||||||
else if (resp->ver == 2 ){
|
else if (response[0] == 2) {
|
||||||
pcp_peer_v2_t* peer_resp = (pcp_peer_v2_t*)resp->next_data;
|
WRITENU16(response + PCP_COMMON_RESPONSE_SIZE + 16, pcp_msg_info->int_port);
|
||||||
peer_resp->ext_port = htons(pcp_msg_info->ext_port);
|
WRITENU16(response + PCP_COMMON_RESPONSE_SIZE + 18, pcp_msg_info->ext_port);
|
||||||
peer_resp->int_port = htons(pcp_msg_info->int_port);
|
WRITENU16(response + PCP_COMMON_RESPONSE_SIZE + 36, pcp_msg_info->peer_port);
|
||||||
peer_resp->peer_port = htons(pcp_msg_info->peer_port);
|
memcpy(response + PCP_COMMON_RESPONSE_SIZE + 20, pcp_msg_info->ext_ip, sizeof(struct in6_addr));
|
||||||
peer_resp->ext_ip = *pcp_msg_info->ext_ip;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* PCP_PEER */
|
#endif /* PCP_PEER */
|
||||||
|
|
||||||
#ifdef PCP_SADSCP
|
#ifdef PCP_SADSCP
|
||||||
else if (resp->r_opcode == 0x83) { /*SADSCP response*/
|
else if (response[1] == 0x83) { /*SADSCP response*/
|
||||||
pcp_sadscp_resp_t *sadscp_resp = (pcp_sadscp_resp_t*)resp->next_data;
|
response[PCP_COMMON_RESPONSE_SIZE + 12]
|
||||||
sadscp_resp->a_r_dscp_value = pcp_msg_info->matched_name<<7;
|
= ((pcp_msg_info->matched_name<<7) & ~(1<<6)) |
|
||||||
sadscp_resp->a_r_dscp_value &= ~(1<<6);
|
(pcp_msg_info->sadscp_dscp & PCP_SADSCP_MASK);
|
||||||
sadscp_resp->a_r_dscp_value |= (pcp_msg_info->sadscp_dscp & PCP_SADSCP_MASK);
|
memset(response + PCP_COMMON_RESPONSE_SIZE + 13, 0, 3);
|
||||||
memset(sadscp_resp->reserved, 0, sizeof(sadscp_resp->reserved));
|
|
||||||
}
|
}
|
||||||
#endif /* PCP_SADSCP */
|
#endif /* PCP_SADSCP */
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue