#63 reject unknown LCP options

Reject all unknown LCP configuration
options by sending LCP conf-reject.
This commit is contained in:
Christian Giese
2022-01-26 13:40:54 +01:00
parent 06fb7599f9
commit b01b61e5a7
3 changed files with 68 additions and 2 deletions
+15
View File
@@ -2774,6 +2774,7 @@ decode_ppp_ip6cp(uint8_t *buf, uint16_t len,
uint16_t ip6cp_len = 0;
uint8_t ip6cp_option_type = 0;
uint8_t ip6cp_option_len = 0;
uint8_t ip6cp_option_index = 0;
if(len < 4 || sp_len < sizeof(bbl_ip6cp_t)) {
return DECODE_ERROR;
@@ -2813,6 +2814,9 @@ decode_ppp_ip6cp(uint8_t *buf, uint16_t len,
case PPP_CODE_CONF_ACK:
case PPP_CODE_CONF_NAK:
while(ip6cp_len >= 2) {
if(ip6cp_option_index < PPP_MAX_OPTIONS) {
ip6cp->option[ip6cp_option_index++] = buf;
}
ip6cp_option_type = *buf;
BUMP_BUFFER(buf, ip6cp_len, sizeof(uint8_t));
ip6cp_option_len = *buf;
@@ -2829,6 +2833,7 @@ decode_ppp_ip6cp(uint8_t *buf, uint16_t len,
ip6cp->ipv6_identifier = *(uint64_t*)buf;
break;
default:
ip6cp->unknown_options = true;
break;
}
BUMP_BUFFER(buf, ip6cp_len, ip6cp_option_len);
@@ -2855,6 +2860,7 @@ decode_ppp_ipcp(uint8_t *buf, uint16_t len,
uint16_t ipcp_len = 0;
uint8_t ipcp_option_type = 0;
uint8_t ipcp_option_len = 0;
uint8_t ipcp_option_index = 0;
if(len < 4 || sp_len < sizeof(bbl_ipcp_t)) {
return DECODE_ERROR;
@@ -2894,6 +2900,9 @@ decode_ppp_ipcp(uint8_t *buf, uint16_t len,
case PPP_CODE_CONF_ACK:
case PPP_CODE_CONF_NAK:
while(ipcp_len >= 2) {
if(ipcp_option_index < PPP_MAX_OPTIONS) {
ipcp->option[ipcp_option_index++] = buf;
}
ipcp_option_type = *buf;
BUMP_BUFFER(buf, ipcp_len, sizeof(uint8_t));
ipcp_option_len = *buf;
@@ -2919,6 +2928,7 @@ decode_ppp_ipcp(uint8_t *buf, uint16_t len,
ipcp->dns2 = *(uint32_t*)buf;
break;
default:
ipcp->unknown_options = true;
break;
}
BUMP_BUFFER(buf, ipcp_len, ipcp_option_len);
@@ -2953,6 +2963,7 @@ decode_ppp_lcp(uint8_t *buf, uint16_t len,
uint16_t lcp_len = 0;
uint8_t lcp_option_type = 0;
uint8_t lcp_option_len = 0;
uint8_t lcp_option_index = 0;
if(len < 4 || sp_len < sizeof(bbl_lcp_t)) {
return DECODE_ERROR;
@@ -3015,6 +3026,9 @@ decode_ppp_lcp(uint8_t *buf, uint16_t len,
case PPP_CODE_CONF_ACK:
case PPP_CODE_CONF_NAK:
while(lcp_len >= 2) {
if(lcp_option_index < PPP_MAX_OPTIONS) {
lcp->option[lcp_option_index++] = buf;
}
lcp_option_type = *buf;
BUMP_BUFFER(buf, lcp_len, sizeof(uint8_t));
lcp_option_len = *buf;
@@ -3037,6 +3051,7 @@ decode_ppp_lcp(uint8_t *buf, uint16_t len,
lcp->magic = *(uint32_t*)buf;
break;
default:
lcp->unknown_options = true;
break;
}
BUMP_BUFFER(buf, lcp_len, lcp_option_len);
+8 -1
View File
@@ -100,6 +100,8 @@
#define PPP_CODE_ECHO_REPLY 10
#define PPP_CODE_DISCARD_REQUEST 11
#define PPP_MAX_OPTIONS 8
#define PAP_CODE_REQUEST 1
#define PAP_CODE_ACK 2
#define PAP_CODE_NAK 3
@@ -529,7 +531,6 @@ struct pppoe_ppp_session_header {
uint16_t protocol;
} __attribute__ ((__packed__));
/*
* PPP LCP Structure
*/
@@ -547,6 +548,8 @@ typedef struct bbl_lcp_ {
uint16_t vendor_value_len;
uint8_t *start;
uint16_t len;
uint8_t *option[PPP_MAX_OPTIONS];
bool unknown_options;
} bbl_lcp_t;
/*
@@ -563,6 +566,8 @@ typedef struct bbl_ipcp_ {
bool option_address;
bool option_dns1;
bool option_dns2;
uint8_t *option[PPP_MAX_OPTIONS];
bool unknown_options;
} bbl_ipcp_t;
/*
@@ -574,6 +579,8 @@ typedef struct bbl_ip6cp_ {
uint8_t *options;
uint8_t options_len;
uint64_t ipv6_identifier;
uint8_t *option[PPP_MAX_OPTIONS];
bool unknown_options;
} bbl_ip6cp_t;
/*
+45 -1
View File
@@ -1155,7 +1155,48 @@ bbl_rx_ipcp(bbl_ethernet_header_t *eth, bbl_interface_s *interface, bbl_session_
}
}
void
/**
* bbl_rx_lcp_conf_reject
*
* This function rejects all unknown LCP configuration
* options by sending LCP conf-reject.
*
* @param session corresponding session
* @param lcp received LCP packet
*/
static void
bbl_rx_lcp_conf_reject(bbl_session_s *session, bbl_lcp_t *lcp) {
uint8_t type;
uint8_t len;
session->lcp_options_len = 0;
for(int i=0; i < PPP_MAX_OPTIONS; i++) {
if(lcp->option[i]) {
type = lcp->option[i][0];
len = lcp->option[i][1];
switch (type) {
case PPP_LCP_OPTION_MRU:
case PPP_LCP_OPTION_AUTH:
case PPP_LCP_OPTION_MAGIC:
break;
default:
if((session->lcp_options_len + len) <= PPP_OPTIONS_BUFFER) {
memcpy(&session->lcp_options[session->lcp_options_len], lcp->option[i], len);
session->lcp_options_len += len;
}
break;
}
}
}
session->lcp_peer_identifier = lcp->identifier;
session->lcp_response_code = PPP_CODE_CONF_REJECT;
session->send_requests |= BBL_SEND_LCP_RESPONSE;
bbl_session_tx_qnode_insert(session);
return;
}
static void
bbl_rx_lcp(bbl_ethernet_header_t *eth, bbl_interface_s *interface, bbl_session_s *session) {
bbl_pppoe_session_t *pppoes;
bbl_lcp_t *lcp;
@@ -1200,6 +1241,9 @@ bbl_rx_lcp(bbl_ethernet_header_t *eth, bbl_interface_s *interface, bbl_session_s
bbl_session_tx_qnode_insert(session);
break;
case PPP_CODE_CONF_REQUEST:
if(lcp->unknown_options) {
return bbl_rx_lcp_conf_reject(session, lcp);
}
session->auth_protocol = lcp->auth;
if(session->access_config->authentication_protocol) {
if(session->access_config->authentication_protocol != lcp->auth) {