1706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*- 2706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Copyright (c) 2001 Brian Somers <brian@Awfulhak.org> 3706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * All rights reserved. 4706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 5706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Redistribution and use in source and binary forms, with or without 6706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * modification, are permitted provided that the following conditions 7706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * are met: 8706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 1. Redistributions of source code must retain the above copyright 9706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * notice, this list of conditions and the following disclaimer. 10706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 2. Redistributions in binary form must reproduce the above copyright 11706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * notice, this list of conditions and the following disclaimer in the 12706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * documentation and/or other materials provided with the distribution. 13706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 14706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * SUCH DAMAGE. 25706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 26706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * $FreeBSD: src/usr.sbin/ppp/ipv6cp.c,v 1.17.10.1.2.1 2010/12/21 17:10:29 kensmith Exp $ 27706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 28706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 29706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/param.h> 30706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/in_systm.h> 31706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/in.h> 32706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/ip.h> 33706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/socket.h> 34706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <net/route.h> 35706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <net/if.h> 36706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <net/if_types.h> 37706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <net/if_dl.h> 38706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/un.h> 39706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 40706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <stdarg.h> 41706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <stdio.h> 42706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <stdlib.h> 43706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <string.h> 44706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <termios.h> 45706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <ifaddrs.h> 46706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 47706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "layer.h" 48706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "defs.h" 49706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "mbuf.h" 50706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "timer.h" 51706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "fsm.h" 52706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "iplist.h" 53706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "throughput.h" 54706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "slcompress.h" 55706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "lqr.h" 56706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "hdlc.h" 57706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "lcp.h" 58706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ncpaddr.h" 59706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ip.h" 60706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ipcp.h" 61706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ipv6cp.h" 62706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "filter.h" 63706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "descriptor.h" 64706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ccp.h" 65706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "link.h" 66706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "mp.h" 67706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NORADIUS 68706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "radius.h" 69706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif 70706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ncp.h" 71706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "bundle.h" 72706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "route.h" 73706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "iface.h" 74706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "log.h" 75706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "proto.h" 76706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "command.h" 77706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "prompt.h" 78706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "async.h" 79706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "physical.h" 80706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "probe.h" 81706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "systems.h" 82706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 83706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 84706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NOINET6 85706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#define IN6ADDR_LINKLOCAL_MCAST_INIT \ 86706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 87706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}} 88706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic const struct in6_addr in6addr_linklocal_mcast = 89706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh IN6ADDR_LINKLOCAL_MCAST_INIT; 90706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 91706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int ipv6cp_LayerUp(struct fsm *); 92706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void ipv6cp_LayerDown(struct fsm *); 93706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void ipv6cp_LayerStart(struct fsm *); 94706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void ipv6cp_LayerFinish(struct fsm *); 95706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void ipv6cp_InitRestartCounter(struct fsm *, int); 96706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void ipv6cp_SendConfigReq(struct fsm *); 97706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void ipv6cp_SentTerminateReq(struct fsm *); 98706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void ipv6cp_SendTerminateAck(struct fsm *, u_char); 99706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void ipv6cp_DecodeConfig(struct fsm *, u_char *, u_char *, int, 100706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct fsm_decode *); 101706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 102706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic struct fsm_callbacks ipv6cp_Callbacks = { 103706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp_LayerUp, 104706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp_LayerDown, 105706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp_LayerStart, 106706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp_LayerFinish, 107706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp_InitRestartCounter, 108706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp_SendConfigReq, 109706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp_SentTerminateReq, 110706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp_SendTerminateAck, 111706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp_DecodeConfig, 112706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_NullRecvResetReq, 113706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_NullRecvResetAck 114706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh}; 115706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 116706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 117706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi YehSetInterfaceID(u_char *ifid, int userandom) 118706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 119706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct ifaddrs *ifa, *ifap = NULL; 120706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct sockaddr_dl *sdl; 121706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh const u_long i32_max = 0xffffffff; 122706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_long r1, r2; 123706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 124706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* configure an interface ID based on Section 4.1 of RFC 2472 */ 125706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memset(ifid, 0, IPV6CP_IFIDLEN); 126706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 127706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 128706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 1) If an IEEE global identifier (EUI-48 or EUI-64) is 129706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * available anywhere on the node, it should be used to construct 130706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * the tentative Interface-Identifier due to its uniqueness 131706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * properties. 132706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 133706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (userandom) 134706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh goto randomid; 135706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (getifaddrs(&ifap) < 0) 136706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh goto randomid; 137706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 138706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 139706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh char *cp; 140706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 141706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (ifa->ifa_addr->sa_family != AF_LINK) 142706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh continue; 143706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 144706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh sdl = (struct sockaddr_dl *)ifa->ifa_addr; 145706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (sdl->sdl_alen < 6) 146706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh continue; 147706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* we're only interested in IEEE hardware addresses */ 148706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch(sdl->sdl_type) { 149706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case IFT_ETHER: 150706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case IFT_FDDI: 151706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case IFT_L2VLAN: 152706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* XXX need more cases? */ 153706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 154706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh default: 155706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh continue; 156706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 157706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 158706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh cp = (char *)(sdl->sdl_data + sdl->sdl_nlen); 159706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ifid[0] = cp[0]; 160706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ifid[0] ^= 0x02; /* reverse the u/l bit*/ 161706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ifid[1] = cp[1]; 162706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ifid[2] = cp[2]; 163706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ifid[3] = 0xff; 164706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ifid[4] = 0xfe; 165706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ifid[5] = cp[3]; 166706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ifid[6] = cp[4]; 167706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ifid[7] = cp[5]; 168706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 169706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh freeifaddrs(ifap); 170706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 171706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 172706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 173706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh freeifaddrs(ifap); 174706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 175706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 176706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 2) If an IEEE global identifier is not available a different source 177706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * of uniqueness should be used. 178706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * XXX: we skip this case. 179706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 180706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 181706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 182706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * 3) If a good source of uniqueness cannot be found, it is 183706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * recommended that a random number be generated. In this case the 184706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * "u" bit of the interface identifier MUST be set to zero (0). 185706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 186706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh randomid: 187706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh randinit(); 188706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh r1 = (((u_long)random()) % i32_max) + 1; 189706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh r2 = (((u_long)random()) % i32_max) + 1; 190706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcpy(ifid, &r1, sizeof(r1)); 191706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcpy(ifid + 4, &r2, sizeof(r2)); 192706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ifid[0] &= 0xfd; 193706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 194706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 195706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 196706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int 197706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipcp_SetIPv6address(struct ipv6cp *ipv6cp, u_char *myifid, u_char *hisifid) 198706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 199706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct bundle *bundle = ipv6cp->fsm.bundle; 200706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct in6_addr myaddr, hisaddr; 201706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct ncprange myrange, range; 202706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct ncpaddr addr; 203706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct sockaddr_storage ssdst, ssgw, ssmask; 204706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct sockaddr *sadst, *sagw, *samask; 205706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 206706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh sadst = (struct sockaddr *)&ssdst; 207706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh sagw = (struct sockaddr *)&ssgw; 208706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh samask = (struct sockaddr *)&ssmask; 209706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 210706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memset(&myaddr, '\0', sizeof myaddr); 211706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memset(&hisaddr, '\0', sizeof hisaddr); 212706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 213706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh myaddr.s6_addr[0] = 0xfe; 214706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh myaddr.s6_addr[1] = 0x80; 215706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcpy(&myaddr.s6_addr[8], myifid, IPV6CP_IFIDLEN); 216706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#if 0 217706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh myaddr.s6_addr[8] |= 0x02; /* set 'universal' bit */ 218706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif 219706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 220706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh hisaddr.s6_addr[0] = 0xfe; 221706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh hisaddr.s6_addr[1] = 0x80; 222706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcpy(&hisaddr.s6_addr[8], hisifid, IPV6CP_IFIDLEN); 223706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#if 0 224706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh hisaddr.s6_addr[8] |= 0x02; /* set 'universal' bit */ 225706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif 226706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 227706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ncpaddr_setip6(&ipv6cp->myaddr, &myaddr); 228706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ncpaddr_setip6(&ipv6cp->hisaddr, &hisaddr); 229706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ncprange_set(&myrange, &ipv6cp->myaddr, 64); 230706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 231706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!iface_Add(bundle->iface, &bundle->ncp, &myrange, &ipv6cp->hisaddr, 232706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh IFACE_ADD_FIRST|IFACE_FORCE_ADD|IFACE_SYSTEM)) 233706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 0; 234706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 235706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!Enabled(bundle, OPT_IFACEALIAS)) 236706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh iface_Clear(bundle->iface, &bundle->ncp, AF_INET6, 237706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh IFACE_CLEAR_ALIASES|IFACE_SYSTEM); 238706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 239706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ncpaddr_setip6(&addr, &in6addr_linklocal_mcast); 240706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ncprange_set(&range, &addr, 32); 241706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh rt_Set(bundle, RTM_ADD, &range, &ipv6cp->myaddr, 1, 0); 242706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 243706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (bundle->ncp.cfg.sendpipe > 0 || bundle->ncp.cfg.recvpipe > 0) { 244706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ncprange_getsa(&myrange, &ssgw, &ssmask); 245706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (ncpaddr_isset(&ipv6cp->hisaddr)) 246706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ncpaddr_getsa(&ipv6cp->hisaddr, &ssdst); 247706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh else 248706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh sadst = NULL; 249706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh rt_Update(bundle, sadst, sagw, samask); 250706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 251706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 252706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (Enabled(bundle, OPT_SROUTES)) 253706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh route_Change(bundle, bundle->ncp.route, &ipv6cp->myaddr, &ipv6cp->hisaddr); 254706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 255706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NORADIUS 256706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (bundle->radius.valid) 257706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh route_Change(bundle, bundle->radius.ipv6routes, &ipv6cp->myaddr, 258706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh &ipv6cp->hisaddr); 259706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif 260706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 261706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 1; /* Ok */ 262706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 263706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 264706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 265706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_Init(struct ipv6cp *ipv6cp, struct bundle *bundle, struct link *l, 266706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh const struct fsm_parent *parent) 267706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 268706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh static const char * const timer_names[] = 269706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh {"IPV6CP restart", "IPV6CP openmode", "IPV6CP stopped"}; 270706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int n; 271706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 272706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Init(&ipv6cp->fsm, "IPV6CP", PROTO_IPV6CP, 1, IPV6CP_MAXCODE, LogIPV6CP, 273706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bundle, l, parent, &ipv6cp_Callbacks, timer_names); 274706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 275706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp->cfg.fsm.timeout = DEF_FSMRETRY; 276706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp->cfg.fsm.maxreq = DEF_FSMTRIES; 277706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp->cfg.fsm.maxtrm = DEF_FSMTRIES; 278706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 279706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh SetInterfaceID(ipv6cp->my_ifid, 0); 280706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh do { 281706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh SetInterfaceID(ipv6cp->his_ifid, 1); 282706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } while (memcmp(ipv6cp->his_ifid, ipv6cp->my_ifid, IPV6CP_IFIDLEN) == 0); 283706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 284706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (probe.ipv6_available) { 285706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh n = 100; 286706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh while (n && 287706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh !ipcp_SetIPv6address(ipv6cp, ipv6cp->my_ifid, ipv6cp->his_ifid)) { 288706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh do { 289706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh n--; 290706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh SetInterfaceID(ipv6cp->my_ifid, 1); 291706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } while (n 292706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh && memcmp(ipv6cp->his_ifid, ipv6cp->my_ifid, IPV6CP_IFIDLEN) == 0); 293706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 294706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 295706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 296706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh throughput_init(&ipv6cp->throughput, SAMPLE_PERIOD); 297706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memset(ipv6cp->Queue, '\0', sizeof ipv6cp->Queue); 298706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp_Setup(ipv6cp); 299706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 300706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 301706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 302706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_Destroy(struct ipv6cp *ipv6cp) 303706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 304706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh throughput_destroy(&ipv6cp->throughput); 305706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 306706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 307706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 308706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_Setup(struct ipv6cp *ipv6cp) 309706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 310706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ncpaddr_init(&ipv6cp->myaddr); 311706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ncpaddr_init(&ipv6cp->hisaddr); 312706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 313706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp->his_reject = 0; 314706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp->my_reject = 0; 315706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 316706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 317706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 318706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_SetLink(struct ipv6cp *ipv6cp, struct link *l) 319706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 320706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp->fsm.link = l; 321706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 322706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 323706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehint 324706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_Show(struct cmdargs const *arg) 325706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 326706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct ipv6cp *ipv6cp = &arg->bundle->ncp.ipv6cp; 327706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 328706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, "%s [%s]\n", ipv6cp->fsm.name, 329706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh State2Nam(ipv6cp->fsm.state)); 330706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (ipv6cp->fsm.state == ST_OPENED) { 331706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " His side: %s\n", 332706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ncpaddr_ntoa(&ipv6cp->hisaddr)); 333706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " My side: %s\n", 334706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ncpaddr_ntoa(&ipv6cp->myaddr)); 335706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " Queued packets: %lu\n", 336706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (unsigned long)ipv6cp_QueueLen(ipv6cp)); 337706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 338706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 339706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, "\nDefaults:\n"); 340706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " FSM retry = %us, max %u Config" 341706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh " REQ%s, %u Term REQ%s\n\n", ipv6cp->cfg.fsm.timeout, 342706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp->cfg.fsm.maxreq, ipv6cp->cfg.fsm.maxreq == 1 ? "" : "s", 343706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp->cfg.fsm.maxtrm, ipv6cp->cfg.fsm.maxtrm == 1 ? "" : "s"); 344706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 345706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh throughput_disp(&ipv6cp->throughput, arg->prompt); 346706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 347706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 0; 348706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 349706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 350706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstruct mbuf * 351706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) 352706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 353706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Got PROTO_IPV6CP from link */ 354706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_settype(bp, MB_IPV6CPIN); 355706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (bundle_Phase(bundle) == PHASE_NETWORK) 356706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Input(&bundle->ncp.ipv6cp.fsm, bp); 357706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh else { 358706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (bundle_Phase(bundle) < PHASE_NETWORK) 359706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogIPV6CP, "%s: Error: Unexpected IPV6CP in phase %s" 360706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh " (ignored)\n", l->name, bundle_PhaseName(bundle)); 361706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 362706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 363706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return NULL; 364706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 365706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 366706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 367706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_AddInOctets(struct ipv6cp *ipv6cp, int n) 368706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 369706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh throughput_addin(&ipv6cp->throughput, n); 370706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 371706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 372706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 373706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_AddOutOctets(struct ipv6cp *ipv6cp, int n) 374706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 375706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh throughput_addout(&ipv6cp->throughput, n); 376706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 377706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 378706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 379706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_IfaceAddrAdded(struct ipv6cp *ipv6cp __unused, 380706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh const struct iface_addr *addr __unused) 381706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 382706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 383706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 384706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 385706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_IfaceAddrDeleted(struct ipv6cp *ipv6cp __unused, 386706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh const struct iface_addr *addr __unused) 387706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 388706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 389706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 390706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehint 391706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_InterfaceUp(struct ipv6cp *ipv6cp) 392706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 393706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!ipcp_SetIPv6address(ipv6cp, ipv6cp->my_ifid, ipv6cp->his_ifid)) { 394706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogERROR, "ipv6cp_InterfaceUp: unable to set ipv6 address\n"); 395706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 0; 396706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 397706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 398706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!iface_SetFlags(ipv6cp->fsm.bundle->iface->name, IFF_UP)) { 399706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogERROR, "ipv6cp_InterfaceUp: Can't set the IFF_UP" 400706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh " flag on %s\n", ipv6cp->fsm.bundle->iface->name); 401706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 0; 402706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 403706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 404706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 1; 405706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 406706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 407706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehsize_t 408706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_QueueLen(struct ipv6cp *ipv6cp) 409706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 410706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mqueue *q; 411706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh size_t result; 412706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 413706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh result = 0; 414706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh for (q = ipv6cp->Queue; q < ipv6cp->Queue + IPV6CP_QUEUES(ipv6cp); q++) 415706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh result += q->len; 416706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 417706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return result; 418706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 419706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 420706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehint 421706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_PushPacket(struct ipv6cp *ipv6cp, struct link *l) 422706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 423706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct bundle *bundle = ipv6cp->fsm.bundle; 424706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mqueue *queue; 425706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mbuf *bp; 426706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int m_len; 427706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_int32_t secs = 0; 428706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh unsigned alivesecs = 0; 429706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 430706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (ipv6cp->fsm.state != ST_OPENED) 431706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 0; 432706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 433706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 434706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * If ccp is not open but is required, do nothing. 435706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 436706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (l->ccp.fsm.state != ST_OPENED && ccp_Required(&l->ccp)) { 437706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogPHASE, "%s: Not transmitting... waiting for CCP\n", l->name); 438706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 0; 439706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 440706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 441706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh queue = ipv6cp->Queue + IPV6CP_QUEUES(ipv6cp) - 1; 442706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh do { 443706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (queue->top) { 444706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bp = m_dequeue(queue); 445706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bp = mbuf_Read(bp, &secs, sizeof secs); 446706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bp = m_pullup(bp); 447706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_len = m_length(bp); 448706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!FilterCheck(MBUF_CTOP(bp), AF_INET6, &bundle->filter.alive, 449706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh &alivesecs)) { 450706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (secs == 0) 451706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh secs = alivesecs; 452706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bundle_StartIdleTimer(bundle, secs); 453706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 454706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh link_PushPacket(l, bp, bundle, 0, PROTO_IPV6); 455706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp_AddOutOctets(ipv6cp, m_len); 456706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 1; 457706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 458706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } while (queue-- != ipv6cp->Queue); 459706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 460706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 0; 461706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 462706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 463706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int 464706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_LayerUp(struct fsm *fp) 465706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 466706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* We're now up */ 467706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct ipv6cp *ipv6cp = fsm2ipv6cp(fp); 468706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh char tbuff[40]; 469706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 470706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogIPV6CP, "%s: LayerUp.\n", fp->link->name); 471706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!ipv6cp_InterfaceUp(ipv6cp)) 472706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 0; 473706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 474706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh snprintf(tbuff, sizeof tbuff, "%s", ncpaddr_ntoa(&ipv6cp->myaddr)); 475706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogIPV6CP, "myaddr %s hisaddr = %s\n", 476706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh tbuff, ncpaddr_ntoa(&ipv6cp->hisaddr)); 477706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 478706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NORADIUS 479706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh radius_Account_Set_Ipv6(&fp->bundle->radacct6, ipv6cp->his_ifid); 480706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh radius_Account(&fp->bundle->radius, &fp->bundle->radacct6, 481706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->bundle->links, RAD_START, &ipv6cp->throughput); 482706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 483706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 484706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * XXX: Avoid duplicate evaluation of filterid between IPCP and 485706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * IPV6CP. When IPCP is enabled and rejected, filterid is not 486706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * evaluated. 487706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 488706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!Enabled(fp->bundle, OPT_IPCP)) { 489706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->bundle->radius.cfg.file && fp->bundle->radius.filterid) 490706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh system_Select(fp->bundle, fp->bundle->radius.filterid, LINKUPFILE, 491706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NULL, NULL); 492706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 493706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif 494706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 495706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 496706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * XXX this stuff should really live in the FSM. Our config should 497706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * associate executable sections in files with events. 498706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 499706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (system_Select(fp->bundle, tbuff, LINKUPFILE, NULL, NULL) < 0) { 500706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 501706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * XXX: Avoid duplicate evaluation of label between IPCP and 502706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * IPV6CP. When IPCP is enabled and rejected, label is not 503706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * evaluated. 504706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 505706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (bundle_GetLabel(fp->bundle) && !Enabled(fp->bundle, OPT_IPCP)) { 506706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (system_Select(fp->bundle, bundle_GetLabel(fp->bundle), 507706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh LINKUPFILE, NULL, NULL) < 0) 508706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh system_Select(fp->bundle, "MYADDR6", LINKUPFILE, NULL, NULL); 509706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else 510706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh system_Select(fp->bundle, "MYADDR6", LINKUPFILE, NULL, NULL); 511706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 512706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 513706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->more.reqs = fp->more.naks = fp->more.rejs = ipv6cp->cfg.fsm.maxreq * 3; 514706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_DisplayPrompts(); 515706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 516706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 1; 517706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 518706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 519706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 520706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_LayerDown(struct fsm *fp) 521706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 522706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* About to come down */ 523706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct ipv6cp *ipv6cp = fsm2ipv6cp(fp); 524706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh static int recursing; 525706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh char addr[40]; 526706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 527706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!recursing++) { 528706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh snprintf(addr, sizeof addr, "%s", ncpaddr_ntoa(&ipv6cp->myaddr)); 529706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogIPV6CP, "%s: LayerDown: %s\n", fp->link->name, addr); 530706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 531706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NORADIUS 532706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh radius_Flush(&fp->bundle->radius); 533706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh radius_Account(&fp->bundle->radius, &fp->bundle->radacct6, 534706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->bundle->links, RAD_STOP, &ipv6cp->throughput); 535706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 536706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 537706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * XXX: Avoid duplicate evaluation of filterid between IPCP and 538706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * IPV6CP. When IPCP is enabled and rejected, filterid is not 539706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * evaluated. 540706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 541706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!Enabled(fp->bundle, OPT_IPCP)) { 542706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->bundle->radius.cfg.file && fp->bundle->radius.filterid) 543706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh system_Select(fp->bundle, fp->bundle->radius.filterid, LINKDOWNFILE, 544706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh NULL, NULL); 545706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 546706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif 547706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 548706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 549706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * XXX this stuff should really live in the FSM. Our config should 550706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * associate executable sections in files with events. 551706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 552706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (system_Select(fp->bundle, addr, LINKDOWNFILE, NULL, NULL) < 0) { 553706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 554706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * XXX: Avoid duplicate evaluation of label between IPCP and 555706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * IPV6CP. When IPCP is enabled and rejected, label is not 556706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * evaluated. 557706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 558706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (bundle_GetLabel(fp->bundle) && !Enabled(fp->bundle, OPT_IPCP)) { 559706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (system_Select(fp->bundle, bundle_GetLabel(fp->bundle), 560706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh LINKDOWNFILE, NULL, NULL) < 0) 561706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh system_Select(fp->bundle, "MYADDR6", LINKDOWNFILE, NULL, NULL); 562706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else 563706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh system_Select(fp->bundle, "MYADDR6", LINKDOWNFILE, NULL, NULL); 564706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 565706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 566706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp_Setup(ipv6cp); 567706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 568706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh recursing--; 569706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 570706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 571706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 572706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_LayerStart(struct fsm *fp) 573706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 574706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* We're about to start up ! */ 575706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct ipv6cp *ipv6cp = fsm2ipv6cp(fp); 576706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 577706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogIPV6CP, "%s: LayerStart.\n", fp->link->name); 578706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh throughput_start(&ipv6cp->throughput, "IPV6CP throughput", 579706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh Enabled(fp->bundle, OPT_THROUGHPUT)); 580706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->more.reqs = fp->more.naks = fp->more.rejs = ipv6cp->cfg.fsm.maxreq * 3; 581706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp->peer_tokenreq = 0; 582706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 583706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 584706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 585706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_LayerFinish(struct fsm *fp) 586706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 587706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* We're now down */ 588706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct ipv6cp *ipv6cp = fsm2ipv6cp(fp); 589706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 590706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogIPV6CP, "%s: LayerFinish.\n", fp->link->name); 591706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh throughput_stop(&ipv6cp->throughput); 592706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh throughput_log(&ipv6cp->throughput, LogIPV6CP, NULL); 593706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 594706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 595706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 596706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_InitRestartCounter(struct fsm *fp, int what) 597706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 598706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Set fsm timer load */ 599706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct ipv6cp *ipv6cp = fsm2ipv6cp(fp); 600706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 601706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->FsmTimer.load = ipv6cp->cfg.fsm.timeout * SECTICKS; 602706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (what) { 603706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case FSM_REQ_TIMER: 604706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->restart = ipv6cp->cfg.fsm.maxreq; 605706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 606706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case FSM_TRM_TIMER: 607706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->restart = ipv6cp->cfg.fsm.maxtrm; 608706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 609706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh default: 610706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fp->restart = 1; 611706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 612706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 613706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 614706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 615706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 616706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_SendConfigReq(struct fsm *fp) 617706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 618706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Send config REQ please */ 619706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct physical *p = link2physical(fp->link); 620706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct ipv6cp *ipv6cp = fsm2ipv6cp(fp); 621706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_char buff[IPV6CP_IFIDLEN+2]; 622706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct fsm_opt *o; 623706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 624706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh o = (struct fsm_opt *)buff; 625706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 626706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if ((p && !physical_IsSync(p)) || !REJECTED(ipv6cp, TY_TOKEN)) { 627706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcpy(o->data, ipv6cp->my_ifid, IPV6CP_IFIDLEN); 628706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh INC_FSM_OPT(TY_TOKEN, IPV6CP_IFIDLEN + 2, o); 629706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 630706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 631706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Output(fp, CODE_CONFIGREQ, fp->reqid, buff, (u_char *)o - buff, 632706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh MB_IPV6CPOUT); 633706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 634706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 635706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 636706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_SentTerminateReq(struct fsm *fp __unused) 637706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 638706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Term REQ just sent by FSM */ 639706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 640706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 641706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 642706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_SendTerminateAck(struct fsm *fp, u_char id) 643706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 644706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Send Term ACK please */ 645706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Output(fp, CODE_TERMACK, id, NULL, 0, MB_IPV6CPOUT); 646706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 647706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 648706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic const char * 649706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehprotoname(unsigned proto) 650706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 651706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh static const char *cftypes[] = { "IFACEID", "COMPPROTO" }; 652706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 653706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (proto > 0 && proto <= sizeof cftypes / sizeof *cftypes) 654706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return cftypes[proto - 1]; 655706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 656706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return NumStr(proto, NULL, 0); 657706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 658706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 659706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 660706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_ValidateInterfaceID(struct ipv6cp *ipv6cp, u_char *ifid, 661706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct fsm_decode *dec) 662706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 663706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct fsm_opt opt; 664706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_char zero[IPV6CP_IFIDLEN]; 665706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 666706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memset(zero, 0, IPV6CP_IFIDLEN); 667706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 668706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (memcmp(ifid, zero, IPV6CP_IFIDLEN) != 0 669706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh && memcmp(ifid, ipv6cp->my_ifid, IPV6CP_IFIDLEN) != 0) 670706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcpy(ipv6cp->his_ifid, ifid, IPV6CP_IFIDLEN); 671706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 672706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh opt.hdr.id = TY_TOKEN; 673706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh opt.hdr.len = IPV6CP_IFIDLEN + 2; 674706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcpy(opt.data, &ipv6cp->his_ifid, IPV6CP_IFIDLEN); 675706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (memcmp(ifid, ipv6cp->his_ifid, IPV6CP_IFIDLEN) == 0) 676706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_ack(dec, &opt); 677706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh else 678706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_nak(dec, &opt); 679706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 680706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 681706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 682706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehipv6cp_DecodeConfig(struct fsm *fp, u_char *cp, u_char *end, int mode_type, 683706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct fsm_decode *dec) 684706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 685706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Deal with incoming PROTO_IPV6CP */ 686706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct ipv6cp *ipv6cp = fsm2ipv6cp(fp); 687706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int n; 688706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh char tbuff[100]; 689706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_char ifid[IPV6CP_IFIDLEN], zero[IPV6CP_IFIDLEN]; 690706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct fsm_opt *opt; 691706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 692706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memset(zero, 0, IPV6CP_IFIDLEN); 693706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 694706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh while (end - cp >= (int)sizeof(opt->hdr)) { 695706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if ((opt = fsm_readopt(&cp)) == NULL) 696706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 697706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 698706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh snprintf(tbuff, sizeof tbuff, " %s[%d]", protoname(opt->hdr.id), 699706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh opt->hdr.len); 700706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 701706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (opt->hdr.id) { 702706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case TY_TOKEN: 703706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcpy(ifid, opt->data, IPV6CP_IFIDLEN); 704706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogIPV6CP, "%s 0x%02x%02x%02x%02x%02x%02x%02x%02x\n", tbuff, 705706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ifid[0], ifid[1], ifid[2], ifid[3], ifid[4], ifid[5], ifid[6], ifid[7]); 706706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 707706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (mode_type) { 708706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case MODE_REQ: 709706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp->peer_tokenreq = 1; 710706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp_ValidateInterfaceID(ipv6cp, ifid, dec); 711706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 712706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 713706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case MODE_NAK: 714706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (memcmp(ifid, zero, IPV6CP_IFIDLEN) == 0) { 715706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE, 716706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh "0x0000000000000000: Unacceptable IntefaceID!\n"); 717706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Close(&ipv6cp->fsm); 718706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else if (memcmp(ifid, ipv6cp->his_ifid, IPV6CP_IFIDLEN) == 0) { 719706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE, 720706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh "0x%02x%02x%02x%02x%02x%02x%02x%02x: " 721706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh "Unacceptable IntefaceID!\n", 722706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ifid[0], ifid[1], ifid[2], ifid[3], 723706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ifid[4], ifid[5], ifid[6], ifid[7]); 724706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else if (memcmp(ifid, ipv6cp->my_ifid, IPV6CP_IFIDLEN) != 0) { 725706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh n = 100; 726706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh while (n && !ipcp_SetIPv6address(ipv6cp, ifid, ipv6cp->his_ifid)) { 727706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh do { 728706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh n--; 729706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh SetInterfaceID(ifid, 1); 730706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } while (n && memcmp(ifid, ipv6cp->his_ifid, IPV6CP_IFIDLEN) == 0); 731706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 732706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 733706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (n == 0) { 734706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE, 735706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh "0x0000000000000000: Unacceptable IntefaceID!\n"); 736706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Close(&ipv6cp->fsm); 737706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { 738706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogIPV6CP, "%s changing IntefaceID: " 739706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh "0x%02x%02x%02x%02x%02x%02x%02x%02x " 740706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh "--> 0x%02x%02x%02x%02x%02x%02x%02x%02x\n", tbuff, 741706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp->my_ifid[0], ipv6cp->my_ifid[1], 742706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp->my_ifid[2], ipv6cp->my_ifid[3], 743706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp->my_ifid[4], ipv6cp->my_ifid[5], 744706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp->my_ifid[6], ipv6cp->my_ifid[7], 745706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ifid[0], ifid[1], ifid[2], ifid[3], 746706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ifid[4], ifid[5], ifid[6], ifid[7]); 747706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcpy(ipv6cp->my_ifid, ifid, IPV6CP_IFIDLEN); 748706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bundle_AdjustFilters(fp->bundle, &ipv6cp->myaddr, NULL); 749706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 750706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 751706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 752706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 753706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case MODE_REJ: 754706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp->his_reject |= (1 << opt->hdr.id); 755706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 756706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 757706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 758706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 759706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh default: 760706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (mode_type != MODE_NOP) { 761706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp->my_reject |= (1 << opt->hdr.id); 762706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_rej(dec, opt); 763706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 764706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 765706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 766706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 767706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 768706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (mode_type != MODE_NOP) { 769706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (mode_type == MODE_REQ && !ipv6cp->peer_tokenreq) { 770706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (dec->rejend == dec->rej && dec->nakend == dec->nak) { 771706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 772706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Pretend the peer has requested a TOKEN. 773706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * We do this to ensure that we only send one NAK if the only 774706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * reason for the NAK is because the peer isn't sending a 775706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * TY_TOKEN REQ. This stops us from repeatedly trying to tell 776706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * the peer that we have to have an IP address on their end. 777706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 778706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp->peer_tokenreq = 1; 779706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 780706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memset(ifid, 0, IPV6CP_IFIDLEN); 781706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ipv6cp_ValidateInterfaceID(ipv6cp, ifid, dec); 782706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 783706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_opt_normalise(dec); 784706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 785706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 786706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif 787