* 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,
if (!wo->opt_local) {
wo->accept_local = 1;
- eui64_magic_nz(wo->ourid);
+ if (!demand)
+ eui64_magic_nz(wo->ourid);
}
if (!wo->opt_remote)
wo->accept_remote = 1;
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);
ether_to_eui64(eui64_t *p_eui64)
{
u_char addr[6];
- char *if_name;
-
- if (get_if_hwaddr(addr, devnam) < 0) {
- if ((if_name = get_first_ethernet()) == NULL) {
- error("no persistent id can be found");
- return 0;
- }
-
- if (get_if_hwaddr(addr, if_name) < 0) {
- error("could not obtain hardware address for %s", if_name);
- return 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
wo->opt_remote = 1;
}
}
-
- if (demand && (eui64_iszero(wo->ourid) || eui64_iszero(wo->hisid))) {
- option_error("local/remote LL address required for demand-dialling\n");
- exit(EXIT_OPTION_ERROR);
- }
}
{
ipv6cp_options *wo = &ipv6cp_wantoptions[u];
+ if (eui64_iszero(wo->hisid)) {
+ /* make up an arbitrary identifier for the peer */
+ eui64_magic_nz(wo->hisid);
+ }
+ if (eui64_iszero(wo->ourid)) {
+ /* make up an arbitrary identifier for us */
+ eui64_magic_nz(wo->ourid);
+ }
+
if (!sif6up(u))
return 0;
if (!sif6addr(u, wo->ourid, wo->hisid))
if (sif6defaultroute(u, wo->ourid, wo->hisid))
default_route_set[u] = 1;
- notice("ipv6_demand_conf");
notice("local LL address %s", llv6_ntoa(wo->ourid));
notice("remote LL address %s", llv6_ntoa(wo->hisid));
/*
* 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;
if (! eui64_equals(ho->hisid, wo->hisid))
warn("Remote LL address changed to %s",
llv6_ntoa(ho->hisid));
- ipv6cp_clear_addrs(f->unit, go->ourid, ho->hisid);
+ ipv6cp_clear_addrs(f->unit, wo->ourid, wo->hisid);
/* Set the interface to the new addresses */
if (!sif6addr(f->unit, go->ourid, ho->hisid)) {