X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fipv6cp.c;h=b5e845a35a9d97a441cd77ee2d7f8a88e76dc4e9;hp=f444348f8dcbd1dfbfb7fa5b6d8776528dbd7fd4;hb=96a47326d0073d66e287fb05fa34d119f46744ed;hpb=820cc91b8b57e1ec52cad6a9efafa128bcda2d7e diff --git a/pppd/ipv6cp.c b/pppd/ipv6cp.c index f444348..b5e845a 100644 --- a/pppd/ipv6cp.c +++ b/pppd/ipv6cp.c @@ -1,21 +1,38 @@ /* - 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. -*/ + * ipv6cp.c - PPP IPV6 Control Protocol. + * + * Copyright (c) 1999 Tommi Komulainen. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Tommi Komulainen + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ /* Original version, based on RFC2023 : @@ -80,25 +97,48 @@ * * ipcp.c - PPP IP Control Protocol. * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. * - * 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 and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University 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. + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu * - * $Id: ipv6cp.c,v 1.6 1999/09/30 19:57:45 masputra Exp $ + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: ipv6cp.c,v 1.18 2003/07/28 12:25:41 carlsonj Exp $ */ -#define RCSID "$Id: ipv6cp.c,v 1.6 1999/09/30 19:57:45 masputra Exp $" +#define RCSID "$Id: ipv6cp.c,v 1.18 2003/07/28 12:25:41 carlsonj Exp $" /* * TODO: @@ -177,33 +217,40 @@ static fsm_callbacks ipv6cp_callbacks = { /* IPV6CP callback routines */ * 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 }, -#if defined(SOL2) + "Use (default) IPv4 address as interface identifier", 1 }, + +#if defined(SOL2) || defined(__linux__) { "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 } }; @@ -276,10 +323,11 @@ static int 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)) ) @@ -291,16 +339,20 @@ setifaceid(argv) * 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; } /* @@ -311,14 +363,35 @@ setifaceid(argv) 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; } +char *llv6_ntoa(eui64_t ifaceid); + +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. */ @@ -679,10 +752,10 @@ ipv6cp_nakci(f, p, len) * If they want to negotiate about interface identifier, we comply. * If they want us to ask for compression, we refuse. */ - while (len > CILEN_VOID) { + while (len >= CILEN_VOID) { GETCHAR(citype, p); GETCHAR(cilen, p); - if( (len -= cilen) < 0 ) + if ( cilen < CILEN_VOID || (len -= cilen) < 0 ) goto bad; next = p + cilen - 2; @@ -916,14 +989,14 @@ ipv6cp_reqci(f, inp, len, reject_if_disagree) 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; @@ -998,7 +1071,10 @@ ipv6_check_options() { ipv6cp_options *wo = &ipv6cp_wantoptions[0]; -#if defined(SOL2) + if (!ipv6cp_protent.enabled_flag) + return; + +#if defined(SOL2) || defined(__linux__) /* * Persistent link-local id is only used when user has not explicitly * configure/hard-code the id @@ -1120,8 +1196,8 @@ ipv6cp_up(f) 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 */ @@ -1203,12 +1279,6 @@ ipv6cp_up(f) 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 @@ -1217,7 +1287,6 @@ ipv6cp_up(f) ipv6cp_script_state = s_up; ipv6cp_script(_PATH_IPV6UP); } -#endif /* !defined(SOL2) */ } @@ -1264,18 +1333,11 @@ ipv6cp_down(f) #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) */ } @@ -1437,7 +1499,7 @@ ipv6cp_printpkt(p, plen, printer, arg) 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; }