* since SVR4 && (SNI || __USLC__) didn't work properly)
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
{ "-ipv6", o_bool, &ipv6cp_protent.enabled_flag,
"Disable IPv6 and IPv6CP", OPT_PRIOSUB | OPT_ALIAS },
- { "ipv6cp-accept-local", o_bool, &ipv6cp_allowoptions[0].accept_local,
+ { "ipv6cp-accept-local", o_bool, &ipv6cp_wantoptions[0].accept_local,
"Accept peer's interface identifier for us", 1 },
- { "ipv6cp-accept-remote", o_bool, &ipv6cp_allowoptions[0].accept_remote,
+ { "ipv6cp-accept-remote", o_bool, &ipv6cp_wantoptions[0].accept_remote,
"Accept peer's interface identifier for itself", 1 },
{ "defaultroute6", o_bool, &ipv6cp_wantoptions[0].default_route,
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);
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;
break;
}
if (!eui64_iszero(wo->hisid) && !wo->accept_remote &&
- !eui64_equals(ifaceid, wo->hisid) &&
- eui64_iszero(go->hisid)) {
+ !eui64_equals(ifaceid, wo->hisid)) {
orc = CONFNAK;
ifaceid = wo->hisid;
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);
{
u_char addr[6];
- if (get_if_hwaddr(addr, devnam) < 0 || get_first_ether_hwaddr(addr) < 0) {
+ if (get_if_hwaddr(addr, devnam) < 0 && get_first_ether_hwaddr(addr) < 0) {
error("ipv6cp: no persistent id can be found");
return 0;
}
* Persistent link-local id is only used when user has not explicitly
* configure/hard-code the id
*/
- if ((wo->use_persistent) && (!wo->opt_local) && (!wo->opt_remote)) {
+ if ((wo->use_persistent) && (!wo->opt_local)) {
/*
* On systems where there are no Ethernet interfaces used, there
/*
* We must have a non-zero LL address for both ends of the link.
*/
+
+ if (!eui64_iszero(wo->hisid) && !wo->accept_remote && (!ho->neg_ifaceid || !eui64_equals(ho->hisid, wo->hisid))) {
+ error("Peer refused to agree to his interface identifier");
+ ipv6cp_close(f->unit, "Refused his interface identifier");
+ return;
+ }
if (!ho->neg_ifaceid)
ho->hisid = wo->hisid;