X-Git-Url: https://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fipv6cp.c;h=7bf5e5a3943203f451aa78aaa6e160707bf1782b;hp=bb7d9a18665e50490ec9032d4538af495344a706;hb=44cd25b6c5a886f3cb615f2f0d8d78c6a52a2030;hpb=a8c240d24e1b254284c06b06de06a66828eeec57 diff --git a/pppd/ipv6cp.c b/pppd/ipv6cp.c index bb7d9a1..7bf5e5a 100644 --- a/pppd/ipv6cp.c +++ b/pppd/ipv6cp.c @@ -1,6 +1,80 @@ /* - * ipv6cp.c - PPP IPV6 Control Protocol. - * + ipv6cp.c - PPP IPV6 Control Protocol. + Copyright (C) 1999 Tommi Komulainen + + 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. +*/ + +/* Original version, based on RFC2023 : + + Copyright (c) 1995, 1996, 1997 Francis.Dupont@inria.fr, INRIA Rocquencourt, + Alain.Durand@imag.fr, IMAG, + Jean-Luc.Richier@imag.fr, IMAG-LSR. + + Copyright (c) 1998, 1999 Francis.Dupont@inria.fr, GIE DYADE, + Alain.Durand@imag.fr, IMAG, + Jean-Luc.Richier@imag.fr, IMAG-LSR. + + Ce travail a été fait au sein du GIE DYADE (Groupement d'Intérêt + Économique ayant pour membres BULL S.A. et l'INRIA). + + Ce logiciel informatique est disponible aux conditions + usuelles dans la recherche, c'est-à-dire qu'il peut + être utilisé, copié, modifié, distribué à l'unique + condition que ce texte soit conservé afin que + l'origine de ce logiciel soit reconnue. + + Le nom de l'Institut National de Recherche en Informatique + et en Automatique (INRIA), de l'IMAG, ou d'une personne morale + ou physique ayant participé à l'élaboration de ce logiciel ne peut + être utilisé sans son accord préalable explicite. + + Ce logiciel est fourni tel quel sans aucune garantie, + support ou responsabilité d'aucune sorte. + Ce logiciel est dérivé de sources d'origine + "University of California at Berkeley" et + "Digital Equipment Corporation" couvertes par des copyrights. + + L'Institut d'Informatique et de Mathématiques Appliquées de Grenoble (IMAG) + est une fédération d'unités mixtes de recherche du CNRS, de l'Institut National + Polytechnique de Grenoble et de l'Université Joseph Fourier regroupant + sept laboratoires dont le laboratoire Logiciels, Systèmes, Réseaux (LSR). + + This work has been done in the context of GIE DYADE (joint R & D venture + between BULL S.A. and INRIA). + + This software is available with usual "research" terms + with the aim of retain credits of the software. + Permission to use, copy, modify and distribute this software for any + purpose and without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies, + and the name of INRIA, IMAG, or any contributor not be used in advertising + or publicity pertaining to this material without the prior explicit + permission. The software is provided "as is" without any + warranties, support or liabilities of any kind. + This software is derived from source code from + "University of California at Berkeley" and + "Digital Equipment Corporation" protected by copyrights. + + Grenoble's Institute of Computer Science and Applied Mathematics (IMAG) + is a federation of seven research units funded by the CNRS, National + Polytechnic Institute of Grenoble and University Joseph Fourier. + The research unit in Software, Systems, Networks (LSR) is member of IMAG. +*/ + +/* * Derived from : * * @@ -21,20 +95,16 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: ipv6cp.c,v 1.1 1999/08/13 01:58:43 paulus Exp $ - * - * - * Original version by Inria (www.inria.fr) - * Modified to match RFC2472 by Tommi Komulainen + * $Id: ipv6cp.c,v 1.7 1999/10/08 01:08:18 masputra Exp $ */ -#ifndef lint -static char rcsid[]="$Id: ipv6cp.c,v 1.1 1999/08/13 01:58:43 paulus Exp $"; -#endif +#define RCSID "$Id: ipv6cp.c,v 1.7 1999/10/08 01:08:18 masputra Exp $" /* * TODO: * + * Proxy Neighbour Discovery. + * * Better defines for selecting the ordering of * interface up / set address. (currently checks for __linux__, * since SVR4 && (SNI || __USLC__) didn't work properly) @@ -48,6 +118,7 @@ static char rcsid[]="$Id: ipv6cp.c,v 1.1 1999/08/13 01:58:43 paulus Exp $"; #include #include #include +#include #include "pppd.h" #include "fsm.h" @@ -56,6 +127,8 @@ static char rcsid[]="$Id: ipv6cp.c,v 1.1 1999/08/13 01:58:43 paulus Exp $"; #include "magic.h" #include "pathnames.h" +static const char rcsid[] = RCSID; + /* global vars */ ipv6cp_options ipv6cp_wantoptions[NUM_PPP]; /* Options that we want to request */ ipv6cp_options ipv6cp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ @@ -103,7 +176,7 @@ static fsm_callbacks ipv6cp_callbacks = { /* IPV6CP callback routines */ /* * Command-line options. */ -static int setifaceid __P((char *arg)); +static int setifaceid __P((char **arg)); static option_t ipv6cp_option_list[] = { { "ipv6", o_special, setifaceid, @@ -112,12 +185,17 @@ static option_t ipv6cp_option_list[] = { "Disable IPv6 and IPv6CP" }, { "-ipv6", o_bool, &ipv6cp_protent.enabled_flag, "Disable IPv6 and IPv6CP" }, + { "+ipv6", o_bool, &ipv6cp_protent.enabled_flag, + "Enable IPv6 and IPv6CP", 1 }, { "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 }, - +#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" }, { "ipv6cp-max-terminate", o_int, &ipv6cp_fsm[0].maxtermtransmits, @@ -167,7 +245,7 @@ struct protent ipv6cp_protent = { ipv6_active_pkt }; -static void ipv6cp_clear_addrs __P((int)); +static void ipv6cp_clear_addrs __P((int, eui64_t, eui64_t)); static void ipv6cp_script __P((char *)); static void ipv6cp_script_done __P((void *)); @@ -195,16 +273,17 @@ static pid_t ipv6cp_script_pid; * setifaceid - set the interface identifiers manually */ static int -setifaceid(arg) - char *arg; +setifaceid(argv) + char **argv; { - char *comma; + char *comma, *arg; ipv6cp_options *wo = &ipv6cp_wantoptions[0]; struct in6_addr addr; -#define VALIDID(a) ( ((a).s6_addr64[0] == 0) && \ - ((a).s6_addr64[1] != 0) ) +#define VALIDID(a) ( (((a).s6_addr32[0] == 0) && ((a).s6_addr32[1] == 0)) && \ + (((a).s6_addr32[2] != 0) || ((a).s6_addr32[3] != 0)) ) + arg = *argv; if ((comma = strchr(arg, ',')) == NULL) comma = arg + strlen(arg); @@ -215,7 +294,7 @@ setifaceid(arg) *comma = '\0'; if (inet_pton(AF_INET6, arg, &addr) == 0 || !VALIDID(addr)) { - option_error("Illegal interface identifier: %s", arg); + option_error("Illegal interface identifier (local): %s", arg); return 0; } @@ -229,13 +308,14 @@ setifaceid(arg) */ if (*comma != 0 && *++comma != '\0') { if (inet_pton(AF_INET6, comma, &addr) == 0 || !VALIDID(addr)) { - option_error("Illegal interface identifier: %s", comma); + option_error("Illegal interface identifier (remote): %s", comma); return 0; } eui64_copy(addr.s6_addr32[2], wo->hisid); wo->opt_remote = 1; } + ipv6cp_protent.enabled_flag = 1; return 1; } @@ -918,6 +998,28 @@ ipv6_check_options() { ipv6cp_options *wo = &ipv6cp_wantoptions[0]; +#if defined(SOL2) + /* + * 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)) { + + /* + * On systems where there are no Ethernet interfaces used, there + * may be other ways to obtain a persistent id. Right now, it + * will fall back to using magic [see eui64_magic] below when + * an EUI-48 from MAC address can't be obtained. Other possibilities + * include obtaining EEPROM serial numbers, or some other unique + * yet persistent number. On Sparc platforms, this is possible, + * but too bad there's no standards yet for x86 machines. + */ + if (ether_to_eui64(&wo->ourid)) { + wo->opt_local = 1; + } + } +#endif + if (!wo->opt_local) { /* init interface identifier */ if (wo->use_ip && eui64_iszero(wo->ourid)) { eui64_setlo32(wo->ourid, ntohl(ipcp_wantoptions[0].ouraddr)); @@ -954,14 +1056,19 @@ ipv6_demand_conf(u) { ipv6cp_options *wo = &ipv6cp_wantoptions[u]; -#if defined(__linux__) || (defined(SVR4) && (defined(SNI) || defined(__USLC__))) - if (!sifup(u, PPP_IPV6)) +#if defined(__linux__) || defined(SOL2) || (defined(SVR4) && (defined(SNI) || defined(__USLC__))) +#if defined(SOL2) + if (!sif6up(u)) return 0; +#else + if (!sifup(u)) + return 0; +#endif /* defined(SOL2) */ #endif if (!sif6addr(u, wo->ourid, wo->hisid)) return 0; #if !defined(__linux__) && !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) - if (!sifup(u, PPP_IPV6)) + if (!sifup(u)) return 0; #endif if (!sifnpmode(u, PPP_IPV6, NPMODE_QUEUE)) @@ -1035,7 +1142,7 @@ ipv6cp_up(f) if (! eui64_equals(ho->hisid, wo->hisid)) warn("Remote LL address changed to %s", llv6_ntoa(ho->hisid)); - ipv6cp_clear_addrs(f->unit); + ipv6cp_clear_addrs(f->unit, go->ourid, ho->hisid); /* Set the interface to the new addresses */ if (!sif6addr(f->unit, go->ourid, ho->hisid)) { @@ -1053,7 +1160,7 @@ ipv6cp_up(f) /* * Set LL addresses */ -#if !defined(__linux__) && !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) +#if !defined(__linux__) && !defined(SOL2) && !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) if (!sif6addr(f->unit, go->ourid, ho->hisid)) { if (debug) warn("sif6addr failed"); @@ -1063,14 +1170,23 @@ ipv6cp_up(f) #endif /* bring the interface up for IPv6 */ - if (!sifup(f->unit, PPP_IPV6)) { +#if defined(SOL2) + if (!sif6up(f->unit)) { if (debug) - warn("sif6up failed"); + warn("sifup failed (IPV6)"); ipv6cp_close(f->unit, "Interface configuration failed"); return; } +#else + if (!sifup(f->unit)) { + if (debug) + warn("sifup failed (IPV6)"); + ipv6cp_close(f->unit, "Interface configuration failed"); + return; + } +#endif /* defined(SOL2) */ -#if defined(__linux__) || (defined(SVR4) && (defined(SNI) || defined(__USLC__))) +#if defined(__linux__) || defined(SOL2) || (defined(SVR4) && (defined(SNI) || defined(__USLC__))) if (!sif6addr(f->unit, go->ourid, ho->hisid)) { if (debug) warn("sif6addr failed"); @@ -1125,12 +1241,19 @@ ipv6cp_down(f) if (demand) { sifnpmode(f->unit, PPP_IPV6, NPMODE_QUEUE); } else { + sifnpmode(f->unit, PPP_IPV6, NPMODE_DROP); #if !defined(__linux__) && !(defined(SVR4) && (defined(SNI) || defined(__USLC))) - sifdown(f->unit, PPP_IPV6); +#if defined(SOL2) + sif6down(f->unit); +#else + sifdown(f->unit); +#endif /* defined(SOL2) */ #endif - ipv6cp_clear_addrs(f->unit); + ipv6cp_clear_addrs(f->unit, + ipv6cp_gotoptions[f->unit].ourid, + ipv6cp_hisoptions[f->unit].hisid); #if defined(__linux__) || (defined(SVR4) && (defined(SNI) || defined(__USLC))) - sifdown(f->unit, PPP_IPV6); + sifdown(f->unit); #endif } @@ -1144,16 +1267,14 @@ ipv6cp_down(f) /* * ipv6cp_clear_addrs() - clear the interface addresses, routes, - * proxy arp entries, etc. + * proxy neighbour discovery entries, etc. */ static void -ipv6cp_clear_addrs(unit) +ipv6cp_clear_addrs(unit, ourid, hisid) int unit; + eui64_t ourid; + eui64_t hisid; { - eui64_t ourid, hisid; - - ourid = ipv6cp_gotoptions[unit].ourid; - hisid = ipv6cp_hisoptions[unit].hisid; cif6addr(unit, ourid, hisid); }