From: pali <7141871+pali@users.noreply.github.com> Date: Sat, 19 Jun 2021 01:03:14 +0000 (+0200) Subject: ipv6cp: Fix enforcing local and peer non-random IPv6 interface identifiers (#283) X-Git-Tag: ppp-2.5.0~70 X-Git-Url: http://git.ozlabs.org/?a=commitdiff_plain;h=93fd8a0916ef6bc2a33b76bf165a847355343693;p=ppp.git 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 --- 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);