ipv6cp.c - PPP IPV6 Control Protocol.
Copyright (C) 1999 Tommi Komulainen <Tommi.Komulainen@iki.fi>
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ Redistribution and use in source and binary forms are permitted
+ provided that the above copyright notice and this paragraph are
+ duplicated in all such forms. The name of the author may not be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/* Original version, based on RFC2023 :
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: ipv6cp.c,v 1.6 1999/09/30 19:57:45 masputra Exp $
+ * $Id: ipv6cp.c,v 1.15 2001/03/22 00:42:33 paulus Exp $
*/
-#define RCSID "$Id: ipv6cp.c,v 1.6 1999/09/30 19:57:45 masputra Exp $"
+#define RCSID "$Id: ipv6cp.c,v 1.15 2001/03/22 00:42:33 paulus Exp $"
/*
* TODO:
* Command-line options.
*/
static int setifaceid __P((char **arg));
+static void printifaceid __P((option_t *,
+ void (*)(void *, char *, ...), void *));
static option_t ipv6cp_option_list[] = {
- { "ipv6", o_special, setifaceid,
- "Set interface identifiers for IPV6" },
+ { "ipv6", o_special, (void *)setifaceid,
+ "Set interface identifiers for IPV6",
+ OPT_A2PRINTER, (void *)printifaceid },
+
+ { "+ipv6", o_bool, &ipv6cp_protent.enabled_flag,
+ "Enable IPv6 and IPv6CP", OPT_PRIO | 1 },
{ "noipv6", o_bool, &ipv6cp_protent.enabled_flag,
- "Disable IPv6 and IPv6CP" },
+ "Disable IPv6 and IPv6CP", OPT_PRIOSUB },
{ "-ipv6", o_bool, &ipv6cp_protent.enabled_flag,
- "Disable IPv6 and IPv6CP" },
- { "+ipv6", o_bool, &ipv6cp_protent.enabled_flag,
- "Enable IPv6 and IPv6CP", 1 },
+ "Disable IPv6 and IPv6CP", OPT_PRIOSUB | OPT_ALIAS },
{ "ipv6cp-accept-local", o_bool, &ipv6cp_allowoptions[0].accept_local,
"Accept peer's interface identifier for us", 1 },
+
{ "ipv6cp-use-ipaddr", o_bool, &ipv6cp_allowoptions[0].use_ip,
- "Use (default) IPv4 address as interface identifier", 0 },
+ "Use (default) IPv4 address as interface identifier", 1 },
+
#if defined(SOL2)
{ "ipv6cp-use-persistent", o_bool, &ipv6cp_wantoptions[0].use_persistent,
"Use uniquely-available persistent value for link local address", 1 },
#endif /* defined(SOL2) */
+
{ "ipv6cp-restart", o_int, &ipv6cp_fsm[0].timeouttime,
- "Set timeout for IPv6CP" },
+ "Set timeout for IPv6CP", OPT_PRIO },
{ "ipv6cp-max-terminate", o_int, &ipv6cp_fsm[0].maxtermtransmits,
- "Set max #xmits for term-reqs" },
+ "Set max #xmits for term-reqs", OPT_PRIO },
{ "ipv6cp-max-configure", o_int, &ipv6cp_fsm[0].maxconfreqtransmits,
- "Set max #xmits for conf-reqs" },
+ "Set max #xmits for conf-reqs", OPT_PRIO },
{ "ipv6cp-max-failure", o_int, &ipv6cp_fsm[0].maxnakloops,
- "Set max #conf-naks for IPv6CP" },
+ "Set max #conf-naks for IPv6CP", OPT_PRIO },
{ NULL }
};
setifaceid(argv)
char **argv;
{
- char *comma, *arg;
+ char *comma, *arg, c;
ipv6cp_options *wo = &ipv6cp_wantoptions[0];
struct in6_addr addr;
-
+ static int prio_local, prio_remote;
+
#define VALIDID(a) ( (((a).s6_addr32[0] == 0) && ((a).s6_addr32[1] == 0)) && \
(((a).s6_addr32[2] != 0) || ((a).s6_addr32[3] != 0)) )
* If comma first character, then no local identifier
*/
if (comma != arg) {
+ c = *comma;
*comma = '\0';
if (inet_pton(AF_INET6, arg, &addr) == 0 || !VALIDID(addr)) {
option_error("Illegal interface identifier (local): %s", arg);
return 0;
}
-
- eui64_copy(addr.s6_addr32[2], wo->ourid);
- wo->opt_local = 1;
- *comma = ',';
+
+ if (option_priority >= prio_local) {
+ eui64_copy(addr.s6_addr32[2], wo->ourid);
+ wo->opt_local = 1;
+ prio_local = option_priority;
+ }
+ *comma = c;
}
/*
option_error("Illegal interface identifier (remote): %s", comma);
return 0;
}
- eui64_copy(addr.s6_addr32[2], wo->hisid);
- wo->opt_remote = 1;
+ if (option_priority >= prio_remote) {
+ eui64_copy(addr.s6_addr32[2], wo->hisid);
+ wo->opt_remote = 1;
+ prio_remote = option_priority;
+ }
}
- ipv6cp_protent.enabled_flag = 1;
+ if (override_value("+ipv6", option_priority, option_source))
+ ipv6cp_protent.enabled_flag = 1;
return 1;
}
+static void
+printifaceid(opt, printer, arg)
+ option_t *opt;
+ void (*printer) __P((void *, char *, ...));
+ void *arg;
+{
+ ipv6cp_options *wo = &ipv6cp_wantoptions[0];
+
+ if (wo->opt_local)
+ printer(arg, "%s", llv6_ntoa(wo->ourid));
+ printer(arg, ",");
+ if (wo->opt_remote)
+ printer(arg, "%s", llv6_ntoa(wo->hisid));
+}
+
/*
* Make a string representation of a network address.
*/
orc = CONFREJ;
break;
}
-#else
- orc = CONFREJ;
- break;
-#endif
ho->neg_vj = 1;
ho->vj_protocol = cishort;
break;
+#else
+ orc = CONFREJ;
+ break;
+#endif
default:
orc = CONFREJ;
{
ipv6cp_options *wo = &ipv6cp_wantoptions[0];
+ if (!ipv6cp_protent.enabled_flag)
+ return;
+
#if defined(SOL2)
/*
* Persistent link-local id is only used when user has not explicitly
return;
}
}
- script_setenv("LLLOCAL", llv6_ntoa(go->ourid));
- script_setenv("LLREMOTE", llv6_ntoa(ho->hisid));
+ script_setenv("LLLOCAL", llv6_ntoa(go->ourid), 0);
+ script_setenv("LLREMOTE", llv6_ntoa(ho->hisid), 0);
#ifdef IPV6CP_COMP
/* set tcp compression */
np_up(f->unit, PPP_IPV6);
ipv6cp_is_up = 1;
- /*
- * In Solaris, neighbor discovery and router advertisement are done
- * automatically by in.ndpd daemon when the interface comes up or down
- * and /etc/inet/ndpd.conf is configured properly
- */
-#if !defined(SOL2)
/*
* Execute the ipv6-up script, like this:
* /etc/ppp/ipv6-up interface tty speed local-LL remote-LL
ipv6cp_script_state = s_up;
ipv6cp_script(_PATH_IPV6UP);
}
-#endif /* !defined(SOL2) */
}
#endif
}
- /*
- * In Solaris, neighbor discovery and router advertisement are done
- * automatically by in.ndpd daemon when the interface comes up or down
- * and /etc/inet/ndpd.conf is configured properly
- */
-#if !defined(SOL2)
/* Execute the ipv6-down script */
if (ipv6cp_script_state == s_up && ipv6cp_script_pid == 0) {
ipv6cp_script_state = s_down;
ipv6cp_script(_PATH_IPV6DOWN);
}
-#endif /* !defined(SOL2) */
}
case TERMREQ:
if (len > 0 && *p >= ' ' && *p < 0x7f) {
printer(arg, " ");
- print_string(p, len, printer, arg);
+ print_string((char *)p, len, printer, arg);
p += len;
len = 0;
}