X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fipv6cp.c;h=356ff84ead4103cb846c31c6e806786b166a33e5;hp=0026f54562e77e3c8b622f8147090fe550385c61;hb=70a8ad3dbd8af3b52d624550fc3343d1849c3f76;hpb=e4bb6771bce69d777bd4d332d57d587467a293a2 diff --git a/pppd/ipv6cp.c b/pppd/ipv6cp.c index 0026f54..356ff84 100644 --- a/pppd/ipv6cp.c +++ b/pppd/ipv6cp.c @@ -1,16 +1,38 @@ /* - ipv6cp.c - PPP IPV6 Control Protocol. - Copyright (C) 1999 Tommi Komulainen - - 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. -*/ + * 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 : @@ -75,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: * - * 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. + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. * - * $Id: ipv6cp.c,v 1.16 2002/09/14 08:10:11 etbe Exp $ + * 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 "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 + * + * 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.21 2005/08/25 23:59:34 paulus Exp $ */ -#define RCSID "$Id: ipv6cp.c,v 1.16 2002/09/14 08:10:11 etbe Exp $" +#define RCSID "$Id: ipv6cp.c,v 1.21 2005/08/25 23:59:34 paulus Exp $" /* * TODO: @@ -106,6 +151,7 @@ */ #include +#include #include #include #include @@ -134,6 +180,16 @@ int no_ifaceid_neg = 0; /* local vars */ static int ipv6cp_is_up; +/* Hook for a plugin to know when IPv6 protocol has come up */ +void (*ipv6_up_hook) __P((void)) = NULL; + +/* Hook for a plugin to know when IPv6 protocol has come down */ +void (*ipv6_down_hook) __P((void)) = NULL; + +/* Notifiers for when IPCPv6 goes up and down */ +struct notifier *ipv6_up_notifier = NULL; +struct notifier *ipv6_down_notifier = NULL; + /* * Callbacks for fsm code. (CI = Configuration Information) */ @@ -141,7 +197,7 @@ static void ipv6cp_resetci __P((fsm *)); /* Reset our CI */ static int ipv6cp_cilen __P((fsm *)); /* Return length of our CI */ static void ipv6cp_addci __P((fsm *, u_char *, int *)); /* Add our CI */ static int ipv6cp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ -static int ipv6cp_nakci __P((fsm *, u_char *, int)); /* Peer nak'd our CI */ +static int ipv6cp_nakci __P((fsm *, u_char *, int, int));/* Peer nak'd our CI */ static int ipv6cp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ static int ipv6cp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */ static void ipv6cp_up __P((fsm *)); /* We're UP */ @@ -193,10 +249,8 @@ static option_t ipv6cp_option_list[] = { { "ipv6cp-use-ipaddr", o_bool, &ipv6cp_allowoptions[0].use_ip, "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", OPT_PRIO }, @@ -625,10 +679,11 @@ bad: * 1 - Nak was good. */ static int -ipv6cp_nakci(f, p, len) +ipv6cp_nakci(f, p, len, treat_as_reject) fsm *f; u_char *p; int len; + int treat_as_reject; { ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; u_char citype, cilen, *next; @@ -674,19 +729,21 @@ ipv6cp_nakci(f, p, len) * from our idea, only if the accept_{local,remote} flag is set. */ NAKCIIFACEID(CI_IFACEID, neg_ifaceid, - if (go->accept_local) { - while (eui64_iszero(ifaceid) || - eui64_equals(ifaceid, go->hisid)) /* bad luck */ - eui64_magic(ifaceid); - try.ourid = ifaceid; - IPV6CPDEBUG(("local LL address %s", llv6_ntoa(ifaceid))); - } - ); + if (treat_as_reject) { + try.neg_ifaceid = 0; + } else if (go->accept_local) { + while (eui64_iszero(ifaceid) || + eui64_equals(ifaceid, go->hisid)) /* bad luck */ + eui64_magic(ifaceid); + try.ourid = ifaceid; + IPV6CPDEBUG(("local LL address %s", llv6_ntoa(ifaceid))); + } + ); #ifdef IPV6CP_COMP NAKCIVJ(CI_COMPRESSTYPE, neg_vj, { - if (cishort == IPV6CP_COMP) { + if (cishort == IPV6CP_COMP && !treat_as_reject) { try.vj_protocol = cishort; } else { try.neg_vj = 0; @@ -707,10 +764,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; @@ -1029,7 +1086,6 @@ ipv6_check_options() 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 @@ -1049,7 +1105,6 @@ ipv6_check_options() wo->opt_local = 1; } } -#endif if (!wo->opt_local) { /* init interface identifier */ if (wo->use_ip && eui64_iszero(wo->ourid)) { @@ -1072,7 +1127,7 @@ ipv6_check_options() if (demand && (eui64_iszero(wo->ourid) || eui64_iszero(wo->hisid))) { option_error("local/remote LL address required for demand-dialling\n"); - exit(1); + exit(EXIT_OPTION_ERROR); } } @@ -1087,15 +1142,8 @@ ipv6_demand_conf(u) { ipv6cp_options *wo = &ipv6cp_wantoptions[u]; -#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__))) @@ -1188,43 +1236,20 @@ ipv6cp_up(f) sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS); } else { - /* - * Set LL addresses - */ -#if !defined(__linux__) && !defined(SOL2) && !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) - if (!sif6addr(f->unit, go->ourid, ho->hisid)) { - if (debug) - warn("sif6addr failed"); - ipv6cp_close(f->unit, "Interface configuration failed"); - return; - } -#endif - /* bring the interface up for IPv6 */ -#if defined(SOL2) if (!sif6up(f->unit)) { if (debug) - warn("sifup failed (IPV6)"); + warn("sif6up 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(SOL2) || (defined(SVR4) && (defined(SNI) || defined(__USLC__))) if (!sif6addr(f->unit, go->ourid, ho->hisid)) { if (debug) warn("sif6addr failed"); ipv6cp_close(f->unit, "Interface configuration failed"); return; } -#endif sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS); notice("local LL address %s", llv6_ntoa(go->ourid)); @@ -1234,6 +1259,10 @@ ipv6cp_up(f) np_up(f->unit, PPP_IPV6); ipv6cp_is_up = 1; + notify(ipv6_up_notifier, 0); + if (ipv6_up_hook) + ipv6_up_hook(); + /* * Execute the ipv6-up script, like this: * /etc/ppp/ipv6-up interface tty speed local-LL remote-LL @@ -1257,6 +1286,9 @@ ipv6cp_down(f) { IPV6CPDEBUG(("ipv6cp: down")); update_link_stats(f->unit); + notify(ipv6_down_notifier, 0); + if (ipv6_down_hook) + ipv6_down_hook(); if (ipv6cp_is_up) { ipv6cp_is_up = 0; np_down(f->unit, PPP_IPV6); @@ -1274,16 +1306,14 @@ ipv6cp_down(f) } else { sifnpmode(f->unit, PPP_IPV6, NPMODE_DROP); #if !defined(__linux__) && !(defined(SVR4) && (defined(SNI) || defined(__USLC))) -#if defined(SOL2) sif6down(f->unit); -#else - sifdown(f->unit); -#endif /* defined(SOL2) */ #endif ipv6cp_clear_addrs(f->unit, ipv6cp_gotoptions[f->unit].ourid, ipv6cp_hisoptions[f->unit].hisid); -#if defined(__linux__) || (defined(SVR4) && (defined(SNI) || defined(__USLC))) +#if defined(__linux__) + sif6down(f->unit); +#elif defined(SVR4) && (defined(SNI) || defined(__USLC)) sifdown(f->unit); #endif } @@ -1371,7 +1401,8 @@ ipv6cp_script(script) argv[6] = ipparam; argv[7] = NULL; - ipv6cp_script_pid = run_program(script, argv, 0, ipv6cp_script_done, NULL); + ipv6cp_script_pid = run_program(script, argv, 0, ipv6cp_script_done, + NULL, 0); } /* @@ -1477,7 +1508,6 @@ ipv6cp_printpkt(p, plen, printer, arg) */ #define IP6_HDRLEN 40 /* bytes */ #define IP6_NHDR_FRAG 44 /* fragment IPv6 header */ -#define IPPROTO_TCP 6 #define TCP_HDRLEN 20 #define TH_FIN 0x01