summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpali <7141871+pali@users.noreply.github.com>2021-06-19 03:03:14 +0200
committerGitHub <noreply@github.com>2021-06-19 11:03:14 +1000
commit93fd8a0916ef6bc2a33b76bf165a847355343693 (patch)
tree38f62ce28dc49a7d42b647e0df3f389bf0bfc6d3
parent5b7ca16d695affb207aa9d619f7393b66d246de8 (diff)
downloadppp-93fd8a0916ef6bc2a33b76bf165a847355343693.tar.gz
ipv6cp: Fix enforcing local and peer non-random IPv6 interface identifiers (#283)
In some cases peer may reject our local IPv6 identifier or may send to us IPV6CP request without any IPv6 identifier or send empty IPv6 identifier (asking as to generate some identifier for him). In these special cases pppd always generated some new random IPv6 identifier and completely ignored the fact that user may already specified IPv6 link local address (used for IPv6 identifier) either at command line or in config file. So properly check pppd options and generate new random IPv6 identifier only in case user did not supply any IPv6 link local address. If pppd was configured to not allow random identifiers and peer rejected our enforced identifiers then pppd connection should be terminated. Signed-off-by: Pali Rohár <pali@kernel.org>
-rw-r--r--pppd/ipv6cp.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/pppd/ipv6cp.c b/pppd/ipv6cp.c
index fef147a..ef03e10 100644
--- a/pppd/ipv6cp.c
+++ b/pppd/ipv6cp.c
@@ -720,7 +720,9 @@ ipv6cp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
NAKCIIFACEID(CI_IFACEID, neg_ifaceid,
if (treat_as_reject) {
try.neg_ifaceid = 0;
- } else if (go->accept_local) {
+ } else if (go->accept_local && !eui64_iszero(ifaceid) && !eui64_equals(ifaceid, go->hisid)) {
+ try.ourid = ifaceid;
+ } else if (eui64_iszero(ifaceid) && !go->opt_local) {
while (eui64_iszero(ifaceid) ||
eui64_equals(ifaceid, go->hisid)) /* bad luck */
eui64_magic(ifaceid);
@@ -772,11 +774,15 @@ ipv6cp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
goto bad;
try.neg_ifaceid = 1;
eui64_get(ifaceid, p);
- if (go->accept_local) {
+ if (go->accept_local && !eui64_iszero(ifaceid) && !eui64_equals(ifaceid, go->hisid)) {
+ try.ourid = ifaceid;
+ } else if (eui64_iszero(ifaceid) && !go->opt_local) {
while (eui64_iszero(ifaceid) ||
eui64_equals(ifaceid, go->hisid)) /* bad luck */
eui64_magic(ifaceid);
try.ourid = ifaceid;
+ } else {
+ try.neg_ifaceid = 0;
}
no.neg_ifaceid = 1;
break;
@@ -955,9 +961,17 @@ ipv6cp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree)
orc = CONFNAK;
if (eui64_iszero(go->hisid)) /* first time, try option */
ifaceid = wo->hisid;
- while (eui64_iszero(ifaceid) ||
- eui64_equals(ifaceid, go->ourid)) /* bad luck */
- eui64_magic(ifaceid);
+ if (eui64_equals(ifaceid, go->ourid)) /* bad luck */
+ eui64_zero(ifaceid);
+ if (eui64_iszero(ifaceid)) {
+ if (wo->opt_remote)
+ ifaceid = wo->hisid;
+ else {
+ while (eui64_iszero(ifaceid) ||
+ eui64_equals(ifaceid, go->ourid)) /* bad luck */
+ eui64_magic(ifaceid);
+ }
+ }
go->hisid = ifaceid;
DECPTR(sizeof(ifaceid), p);
eui64_put(ifaceid, p);