1706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh/*- 2706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Copyright (c) 1998 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/mp.c,v 1.55.26.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.h> 31706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/in_systm.h> 32706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <netinet/ip.h> 33706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <arpa/inet.h> 34706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <net/if_dl.h> 35706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/socket.h> 36706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <sys/un.h> 37706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 38706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <errno.h> 39706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <paths.h> 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 <sys/stat.h> 45706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <termios.h> 46706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include <unistd.h> 47706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 48706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "layer.h" 49706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NONAT 50706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "nat_cmd.h" 51706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif 52706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "vjcomp.h" 53706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ua.h" 54706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "defs.h" 55706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "command.h" 56706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "mbuf.h" 57706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "log.h" 58706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "timer.h" 59706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "fsm.h" 60706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "iplist.h" 61706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "throughput.h" 62706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "slcompress.h" 63706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "lqr.h" 64706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "hdlc.h" 65706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ncpaddr.h" 66706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ipcp.h" 67706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "auth.h" 68706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "lcp.h" 69706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "async.h" 70706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ccp.h" 71706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "link.h" 72706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "descriptor.h" 73706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "physical.h" 74706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "chat.h" 75706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "proto.h" 76706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "filter.h" 77706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "mp.h" 78706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "chap.h" 79706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "cbcp.h" 80706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "datalink.h" 81706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NORADIUS 82706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "radius.h" 83706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif 84706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ipv6cp.h" 85706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "ncp.h" 86706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "bundle.h" 87706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "prompt.h" 88706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "id.h" 89706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#include "arp.h" 90706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 91706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 92706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehpeerid_Init(struct peerid *peer) 93706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 94706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh peer->enddisc.class = 0; 95706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *peer->enddisc.address = '\0'; 96706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh peer->enddisc.len = 0; 97706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *peer->authname = '\0'; 98706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 99706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 100706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehint 101706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehpeerid_Equal(const struct peerid *p1, const struct peerid *p2) 102706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 103706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return !strcmp(p1->authname, p2->authname) && 104706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh p1->enddisc.class == p2->enddisc.class && 105706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh p1->enddisc.len == p2->enddisc.len && 106706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh !memcmp(p1->enddisc.address, p2->enddisc.address, p1->enddisc.len); 107706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 108706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 109706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic u_int32_t 110706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehinc_seq(unsigned is12bit, u_int32_t seq) 111706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 112706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh seq++; 113706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (is12bit) { 114706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (seq & 0xfffff000) 115706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh seq = 0; 116706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else if (seq & 0xff000000) 117706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh seq = 0; 118706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return seq; 119706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 120706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 121706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int 122706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehisbefore(unsigned is12bit, u_int32_t seq1, u_int32_t seq2) 123706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 124706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_int32_t max = (is12bit ? 0xfff : 0xffffff) - 0x200; 125706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 126706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (seq1 > max) { 127706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (seq2 < 0x200 || seq2 > seq1) 128706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 1; 129706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else if ((seq1 > 0x200 || seq2 <= max) && seq1 < seq2) 130706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 1; 131706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 132706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 0; 133706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 134706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 135706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int 136706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_ReadHeader(struct mp *mp, struct mbuf *m, struct mp_header *header) 137706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 138706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (mp->local_is12bit) { 139706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_int16_t val; 140706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 141706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ua_ntohs(MBUF_CTOP(m), &val); 142706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (val & 0x3000) { 143706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogWARN, "Oops - MP header without required zero bits\n"); 144706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 0; 145706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 146706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh header->begin = val & 0x8000 ? 1 : 0; 147706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh header->end = val & 0x4000 ? 1 : 0; 148706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh header->seq = val & 0x0fff; 149706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 2; 150706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { 151706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ua_ntohl(MBUF_CTOP(m), &header->seq); 152706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (header->seq & 0x3f000000) { 153706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogWARN, "Oops - MP header without required zero bits\n"); 154706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 0; 155706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 156706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh header->begin = header->seq & 0x80000000 ? 1 : 0; 157706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh header->end = header->seq & 0x40000000 ? 1 : 0; 158706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh header->seq &= 0x00ffffff; 159706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 4; 160706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 161706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 162706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 163706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 164706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_LayerStart(void *v __unused, struct fsm *fp __unused) 165706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 166706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* The given FSM (ccp) is about to start up ! */ 167706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 168706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 169706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 170706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_LayerUp(void *v __unused, struct fsm *fp) 171706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 172706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* The given fsm (ccp) is now up */ 173706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 174706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bundle_CalculateBandwidth(fp->bundle); /* Against ccp_MTUOverhead */ 175706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 176706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 177706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 178706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_LayerDown(void *v __unused, struct fsm *fp __unused) 179706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 180706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* The given FSM (ccp) has been told to come down */ 181706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 182706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 183706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 184706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_LayerFinish(void *v __unused, struct fsm *fp) 185706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 186706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* The given fsm (ccp) is now down */ 187706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (fp->state == ST_CLOSED && fp->open_mode == OPEN_PASSIVE) 188706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Open(fp); /* CCP goes to ST_STOPPED */ 189706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 190706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 191706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 192706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_UpDown(void *v) 193706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 194706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mp *mp = (struct mp *)v; 195706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int percent; 196706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 197706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh percent = MAX(mp->link.stats.total.in.OctetsPerSecond, 198706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->link.stats.total.out.OctetsPerSecond) * 800 / 199706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->bundle->bandwidth; 200706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (percent >= mp->cfg.autoload.max) { 201706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogDEBUG, "%d%% saturation - bring a link up ?\n", percent); 202706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bundle_AutoAdjust(mp->bundle, percent, AUTO_UP); 203706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else if (percent <= mp->cfg.autoload.min) { 204706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogDEBUG, "%d%% saturation - bring a link down ?\n", percent); 205706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bundle_AutoAdjust(mp->bundle, percent, AUTO_DOWN); 206706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 207706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 208706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 209706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 210706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_StopAutoloadTimer(struct mp *mp) 211706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 212706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh throughput_stop(&mp->link.stats.total); 213706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 214706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 215706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 216706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_CheckAutoloadTimer(struct mp *mp) 217706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 218706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (mp->link.stats.total.SamplePeriod != mp->cfg.autoload.period) { 219706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh throughput_destroy(&mp->link.stats.total); 220706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh throughput_init(&mp->link.stats.total, mp->cfg.autoload.period); 221706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh throughput_callback(&mp->link.stats.total, mp_UpDown, mp); 222706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 223706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 224706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (bundle_WantAutoloadTimer(mp->bundle)) 225706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh throughput_start(&mp->link.stats.total, "MP throughput", 1); 226706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh else 227706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp_StopAutoloadTimer(mp); 228706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 229706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 230706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 231706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_RestartAutoloadTimer(struct mp *mp) 232706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 233706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (mp->link.stats.total.SamplePeriod != mp->cfg.autoload.period) 234706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp_CheckAutoloadTimer(mp); 235706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh else 236706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh throughput_clear(&mp->link.stats.total, THROUGHPUT_OVERALL, NULL); 237706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 238706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 239706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 240706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_Init(struct mp *mp, struct bundle *bundle) 241706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 242706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->peer_is12bit = mp->local_is12bit = 0; 243706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->peer_mrru = mp->local_mrru = 0; 244706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 245706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh peerid_Init(&mp->peer); 246706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 247706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->out.seq = 0; 248706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->out.link = 0; 249706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->out.af = AF_INET; 250706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->seq.min_in = 0; 251706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->seq.next_in = 0; 252706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->inbufs = NULL; 253706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->bundle = bundle; 254706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 255706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->link.type = LOGICAL_LINK; 256706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->link.name = "mp"; 257706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->link.len = sizeof *mp; 258706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 259706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.autoload.period = SAMPLE_PERIOD; 260706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.autoload.min = mp->cfg.autoload.max = 0; 261706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh throughput_init(&mp->link.stats.total, mp->cfg.autoload.period); 262706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh throughput_callback(&mp->link.stats.total, mp_UpDown, mp); 263706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->link.stats.parent = NULL; 264706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->link.stats.gather = 0; /* Let the physical links gather stats */ 265706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memset(mp->link.Queue, '\0', sizeof mp->link.Queue); 266706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memset(mp->link.proto_in, '\0', sizeof mp->link.proto_in); 267706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memset(mp->link.proto_out, '\0', sizeof mp->link.proto_out); 268706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 269706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->fsmp.LayerStart = mp_LayerStart; 270706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->fsmp.LayerUp = mp_LayerUp; 271706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->fsmp.LayerDown = mp_LayerDown; 272706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->fsmp.LayerFinish = mp_LayerFinish; 273706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->fsmp.object = mp; 274706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 275706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mpserver_Init(&mp->server); 276706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 277706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.mrru = 0; 278706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.shortseq = NEG_ENABLED|NEG_ACCEPTED; 279706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.negenddisc = NEG_ENABLED|NEG_ACCEPTED; 280706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.enddisc.class = 0; 281706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *mp->cfg.enddisc.address = '\0'; 282706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.enddisc.len = 0; 283706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 284706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh lcp_Init(&mp->link.lcp, mp->bundle, &mp->link, NULL); 285706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ccp_Init(&mp->link.ccp, mp->bundle, &mp->link, &mp->fsmp); 286706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 287706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh link_EmptyStack(&mp->link); 288706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh link_Stack(&mp->link, &protolayer); 289706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh link_Stack(&mp->link, &ccplayer); 290706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh link_Stack(&mp->link, &vjlayer); 291706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#ifndef NONAT 292706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh link_Stack(&mp->link, &natlayer); 293706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh#endif 294706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 295706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 296706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehint 297706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_Up(struct mp *mp, struct datalink *dl) 298706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 299706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct lcp *lcp = &dl->physical->link.lcp; 300706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 301706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (mp->active) { 302706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* We're adding a link - do a last validation on our parameters */ 303706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!peerid_Equal(&dl->peer, &mp->peer)) { 304706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogPHASE, "%s: Inappropriate peer !\n", dl->name); 305706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogPHASE, " Attached to peer %s/%s\n", mp->peer.authname, 306706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp_Enddisc(mp->peer.enddisc.class, mp->peer.enddisc.address, 307706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->peer.enddisc.len)); 308706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogPHASE, " New link is peer %s/%s\n", dl->peer.authname, 309706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp_Enddisc(dl->peer.enddisc.class, dl->peer.enddisc.address, 310706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dl->peer.enddisc.len)); 311706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return MP_FAILED; 312706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 313706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (mp->local_mrru != lcp->want_mrru || 314706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->peer_mrru != lcp->his_mrru || 315706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->local_is12bit != lcp->want_shortseq || 316706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->peer_is12bit != lcp->his_shortseq) { 317706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogPHASE, "%s: Invalid MRRU/SHORTSEQ MP parameters !\n", 318706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dl->name); 319706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return MP_FAILED; 320706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 321706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return MP_ADDED; 322706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { 323706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* First link in multilink mode */ 324706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 325706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->local_mrru = lcp->want_mrru; 326706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->peer_mrru = lcp->his_mrru; 327706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->local_is12bit = lcp->want_shortseq; 328706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->peer_is12bit = lcp->his_shortseq; 329706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->peer = dl->peer; 330706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 331706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh throughput_destroy(&mp->link.stats.total); 332706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh throughput_init(&mp->link.stats.total, mp->cfg.autoload.period); 333706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh throughput_callback(&mp->link.stats.total, mp_UpDown, mp); 334706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memset(mp->link.Queue, '\0', sizeof mp->link.Queue); 335706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memset(mp->link.proto_in, '\0', sizeof mp->link.proto_in); 336706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memset(mp->link.proto_out, '\0', sizeof mp->link.proto_out); 337706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 338706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Tell the link who it belongs to */ 339706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dl->physical->link.stats.parent = &mp->link.stats.total; 340706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 341706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->out.seq = 0; 342706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->out.link = 0; 343706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->out.af = AF_INET; 344706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->seq.min_in = 0; 345706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->seq.next_in = 0; 346706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 347706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 348706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Now we create our server socket. 349706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * If it already exists, join it. Otherwise, create and own it 350706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 351706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (mpserver_Open(&mp->server, &mp->peer)) { 352706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case MPSERVER_CONNECTED: 353706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogPHASE, "mp: Transfer link on %s\n", 354706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->server.socket.sun_path); 355706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->server.send.dl = dl; /* Defer 'till it's safe to send */ 356706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return MP_LINKSENT; 357706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case MPSERVER_FAILED: 358706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return MP_FAILED; 359706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case MPSERVER_LISTENING: 360706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogPHASE, "mp: Listening on %s\n", mp->server.socket.sun_path); 361706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogPHASE, " First link: %s\n", dl->name); 362706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 363706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Re-point our NCP layers at our MP link */ 364706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ncp_SetLink(&mp->bundle->ncp, &mp->link); 365706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 366706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Our lcp's already up 'cos of the NULL parent */ 367706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (ccp_SetOpenMode(&mp->link.ccp)) { 368706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Up(&mp->link.ccp.fsm); 369706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm_Open(&mp->link.ccp.fsm); 370706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 371706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 372706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->active = 1; 373706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 374706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 375706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 376706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 377706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return MP_UP; 378706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 379706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 380706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 381706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_Down(struct mp *mp) 382706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 383706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (mp->active) { 384706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mbuf *next; 385706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 386706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Stop that ! */ 387706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp_StopAutoloadTimer(mp); 388706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 389706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Don't want any more of these */ 390706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mpserver_Close(&mp->server); 391706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 392706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* CCP goes down with a bang */ 393706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fsm2initial(&mp->link.ccp.fsm); 394706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 395706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Received fragments go in the bit-bucket */ 396706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh while (mp->inbufs) { 397706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh next = mp->inbufs->m_nextpkt; 398706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(mp->inbufs); 399706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->inbufs = next; 400706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 401706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 402706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh peerid_Init(&mp->peer); 403706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->active = 0; 404706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 405706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 406706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 407706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 408706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_linkInit(struct mp_link *mplink) 409706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 410706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mplink->seq = 0; 411706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mplink->bandwidth = 0; 412706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 413706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 414706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 415706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_Assemble(struct mp *mp, struct mbuf *m, struct physical *p) 416706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 417706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mp_header mh, h; 418706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mbuf *q, *last; 419706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_int32_t seq; 420706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 421706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 422706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * When `m' and `p' are NULL, it means our oldest link has gone down. 423706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * We want to determine a new min, and process any intermediate stuff 424706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * as normal 425706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 426706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 427706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (m && mp_ReadHeader(mp, m, &mh) == 0) { 428706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(m); 429706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 430706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 431706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 432706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (p) { 433706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh seq = p->dl->mp.seq; 434706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh p->dl->mp.seq = mh.seq; 435706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else 436706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh seq = mp->seq.min_in; 437706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 438706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (mp->seq.min_in == seq) { 439706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 440706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * We've received new data on the link that has our min (oldest) seq. 441706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Figure out which link now has the smallest (oldest) seq. 442706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 443706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct datalink *dl; 444706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 445706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->seq.min_in = (u_int32_t)-1; 446706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh for (dl = mp->bundle->links; dl; dl = dl->next) 447706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (dl->state == DATALINK_OPEN && 448706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (mp->seq.min_in == (u_int32_t)-1 || 449706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh isbefore(mp->local_is12bit, dl->mp.seq, mp->seq.min_in))) 450706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->seq.min_in = dl->mp.seq; 451706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 452706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 453706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 454706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Now process as many of our fragments as we can, adding our new 455706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * fragment in as we go, and ordering with the oldest at the top of 456706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * the queue. 457706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 458706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 459706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh last = NULL; 460706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh seq = mp->seq.next_in; 461706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh q = mp->inbufs; 462706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh while (q || m) { 463706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!q) { 464706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (last) 465706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh last->m_nextpkt = m; 466706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh else 467706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->inbufs = m; 468706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh q = m; 469706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m = NULL; 470706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh h = mh; 471706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { 472706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp_ReadHeader(mp, q, &h); 473706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 474706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (m && isbefore(mp->local_is12bit, mh.seq, h.seq)) { 475706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Our received fragment fits in before this one, so link it in */ 476706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (last) 477706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh last->m_nextpkt = m; 478706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh else 479706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->inbufs = m; 480706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m->m_nextpkt = q; 481706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh q = m; 482706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh h = mh; 483706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m = NULL; 484706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 485706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 486706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 487706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (h.seq != seq) { 488706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* we're missing something :-( */ 489706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (isbefore(mp->local_is12bit, seq, mp->seq.min_in)) { 490706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* we're never gonna get it */ 491706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mbuf *next; 492706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 493706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Zap all older fragments */ 494706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh while (mp->inbufs != q) { 495706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogDEBUG, "Drop frag\n"); 496706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh next = mp->inbufs->m_nextpkt; 497706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(mp->inbufs); 498706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->inbufs = next; 499706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 500706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 501706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 502706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Zap everything until the next `end' fragment OR just before 503706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * the next `begin' fragment OR 'till seq.min_in - whichever 504706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * comes first. 505706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 506706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh do { 507706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp_ReadHeader(mp, mp->inbufs, &h); 508706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (h.begin) { 509706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* We might be able to process this ! */ 510706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh h.seq--; /* We're gonna look for fragment with h.seq+1 */ 511706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 512706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 513706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh next = mp->inbufs->m_nextpkt; 514706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogDEBUG, "Drop frag %u\n", h.seq); 515706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(mp->inbufs); 516706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->inbufs = next; 517706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } while (mp->inbufs && (isbefore(mp->local_is12bit, mp->seq.min_in, 518706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh h.seq) || h.end)); 519706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 520706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 521706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Continue processing things from here. 522706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * This deals with the possibility that we received a fragment 523706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * on the slowest link that invalidates some of our data (because 524706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * of the hole at `q'), but where there are subsequent `whole' 525706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * packets that have already been received. 526706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 527706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 528706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->seq.next_in = seq = inc_seq(mp->local_is12bit, h.seq); 529706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh last = NULL; 530706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh q = mp->inbufs; 531706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else 532706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* we may still receive the missing fragment */ 533706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 534706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else if (h.end) { 535706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* We've got something, reassemble */ 536706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mbuf **frag = &q; 537706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int len; 538706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh long long first = -1; 539706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 540706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh do { 541706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *frag = mp->inbufs; 542706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->inbufs = mp->inbufs->m_nextpkt; 543706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh len = mp_ReadHeader(mp, *frag, &h); 544706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (first == -1) 545706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh first = h.seq; 546706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (frag == &q && !h.begin) { 547706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogWARN, "Oops - MP frag %lu should have a begin flag\n", 548706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (u_long)h.seq); 549706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(q); 550706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh q = NULL; 551706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else if (frag != &q && h.begin) { 552706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogWARN, "Oops - MP frag %lu should have an end flag\n", 553706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (u_long)h.seq - 1); 554706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 555706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Stuff our fragment back at the front of the queue and zap 556706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * our half-assembled packet. 557706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 558706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*frag)->m_nextpkt = mp->inbufs; 559706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->inbufs = *frag; 560706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *frag = NULL; 561706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(q); 562706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh q = NULL; 563706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh frag = &q; 564706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh h.end = 0; /* just in case it's a whole packet */ 565706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { 566706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*frag)->m_offset += len; 567706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*frag)->m_len -= len; 568706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (*frag)->m_nextpkt = NULL; 569706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh do 570706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh frag = &(*frag)->m_next; 571706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh while (*frag != NULL); 572706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 573706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } while (!h.end); 574706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 575706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (q) { 576706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh q = m_pullup(q); 577706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogDEBUG, "MP: Reassembled frags %lu-%lu, length %zd\n", 578706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (u_long)first, (u_long)h.seq, m_length(q)); 579706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh link_PullPacket(&mp->link, MBUF_CTOP(q), q->m_len, mp->bundle); 580706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(q); 581706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 582706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 583706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->seq.next_in = seq = inc_seq(mp->local_is12bit, h.seq); 584706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh last = NULL; 585706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh q = mp->inbufs; 586706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { 587706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Look for the next fragment */ 588706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh seq = inc_seq(mp->local_is12bit, seq); 589706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh last = q; 590706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh q = q->m_nextpkt; 591706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 592706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 593706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 594706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (m) { 595706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* We still have to find a home for our new fragment */ 596706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh last = NULL; 597706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh for (q = mp->inbufs; q; last = q, q = q->m_nextpkt) { 598706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp_ReadHeader(mp, q, &h); 599706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (isbefore(mp->local_is12bit, mh.seq, h.seq)) 600706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 601706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 602706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Our received fragment fits in here */ 603706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (last) 604706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh last->m_nextpkt = m; 605706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh else 606706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->inbufs = m; 607706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m->m_nextpkt = q; 608706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 609706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 610706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 611706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstruct mbuf * 612706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) 613706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 614706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct physical *p = link2physical(l); 615706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 616706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!bundle->ncp.mp.active) 617706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Let someone else deal with it ! */ 618706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return bp; 619706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 620706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (p == NULL) { 621706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogWARN, "DecodePacket: Can't do MP inside MP !\n"); 622706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_freem(bp); 623706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { 624706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_settype(bp, MB_MPIN); 625706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp_Assemble(&bundle->ncp.mp, bp, p); 626706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 627706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 628706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return NULL; 629706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 630706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 631706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 632706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_Output(struct mp *mp, struct bundle *bundle, struct link *l, 633706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mbuf *m, u_int32_t begin, u_int32_t end) 634706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 635706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh char prepend[4]; 636706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 637706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Stuff an MP header on the front of our packet and send it */ 638706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 639706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (mp->peer_is12bit) { 640706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_int16_t val; 641706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 642706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh val = (begin << 15) | (end << 14) | (u_int16_t)mp->out.seq; 643706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ua_htons(&val, prepend); 644706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m = m_prepend(m, prepend, 2, 0); 645706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { 646706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_int32_t val; 647706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 648706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh val = (begin << 31) | (end << 30) | (u_int32_t)mp->out.seq; 649706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ua_htonl(&val, prepend); 650706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m = m_prepend(m, prepend, 4, 0); 651706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 652706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (log_IsKept(LogDEBUG)) 653706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogDEBUG, "MP[frag %d]: Send %zd bytes on link `%s'\n", 654706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->out.seq, m_length(m), l->name); 655706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->out.seq = inc_seq(mp->peer_is12bit, mp->out.seq); 656706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 657706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (l->ccp.fsm.state != ST_OPENED && ccp_Required(&l->ccp)) { 658706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogPHASE, "%s: Not transmitting... waiting for CCP\n", l->name); 659706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return; 660706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 661706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 662706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh link_PushPacket(l, m, bundle, LINK_QUEUES(l) - 1, PROTO_MP); 663706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 664706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 665706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehint 666706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_FillPhysicalQueues(struct bundle *bundle) 667706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 668706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mp *mp = &bundle->ncp.mp; 669706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct datalink *dl, *fdl; 670706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh size_t total, add, len; 671706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int thislink, nlinks, nopenlinks, sendasip; 672706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh u_int32_t begin, end; 673706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mbuf *m, *mo; 674706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct link *bestlink; 675706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 676706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh thislink = nlinks = nopenlinks = 0; 677706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh for (fdl = NULL, dl = bundle->links; dl; dl = dl->next) { 678706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Include non-open links here as mp->out.link will stay more correct */ 679706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!fdl) { 680706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (thislink == mp->out.link) 681706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fdl = dl; 682706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh else 683706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh thislink++; 684706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 685706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh nlinks++; 686706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (dl->state == DATALINK_OPEN) 687706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh nopenlinks++; 688706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 689706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 690706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!fdl) { 691706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh fdl = bundle->links; 692706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!fdl) 693706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 0; 694706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh thislink = 0; 695706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 696706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 697706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh total = 0; 698706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh for (dl = fdl; nlinks > 0; dl = dl->next, nlinks--, thislink++) { 699706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!dl) { 700706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dl = bundle->links; 701706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh thislink = 0; 702706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 703706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 704706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (dl->state != DATALINK_OPEN) 705706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh continue; 706706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 707706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (dl->physical->out) 708706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* this link has suffered a short write. Let it continue */ 709706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh continue; 710706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 711706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh add = link_QueueLen(&dl->physical->link); 712706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (add) { 713706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* this link has got stuff already queued. Let it continue */ 714706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh total += add; 715706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh continue; 716706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 717706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 718706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!mp_QueueLen(mp)) { 719706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int mrutoosmall; 720706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 721706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 722706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * If there's only a single open link in our bundle and we haven't got 723706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * MP level link compression, queue outbound traffic directly via that 724706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * link's protocol stack rather than using the MP link. This results 725706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * in the outbound traffic going out as PROTO_IP or PROTO_IPV6 rather 726706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * than PROTO_MP. 727706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 728706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 729706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mrutoosmall = 0; 730706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh sendasip = nopenlinks < 2; 731706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (sendasip) { 732706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (dl->physical->link.lcp.his_mru < mp->peer_mrru) { 733706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 734706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Actually, forget it. This test is done against the MRRU rather 735706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * than the packet size so that we don't end up sending some data 736706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * in MP fragments and some data in PROTO_IP packets. That's just 737706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * too likely to upset some ppp implementations. 738706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 739706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mrutoosmall = 1; 740706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh sendasip = 0; 741706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 742706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 743706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 744706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bestlink = sendasip ? &dl->physical->link : &mp->link; 745706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!ncp_PushPacket(&bundle->ncp, &mp->out.af, bestlink)) 746706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; /* Nothing else to send */ 747706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 748706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (mrutoosmall) 749706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogDEBUG, "Don't send data as PROTO_IP, MRU < MRRU\n"); 750706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh else if (sendasip) 751706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogDEBUG, "Sending data as PROTO_IP, not PROTO_MP\n"); 752706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 753706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (sendasip) { 754706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh add = link_QueueLen(&dl->physical->link); 755706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (add) { 756706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* this link has got stuff already queued. Let it continue */ 757706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh total += add; 758706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh continue; 759706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 760706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 761706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 762706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 763706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m = link_Dequeue(&mp->link); 764706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (m) { 765706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh len = m_length(m); 766706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh begin = 1; 767706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh end = 0; 768706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 769706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh while (!end) { 770706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (dl->state == DATALINK_OPEN) { 771706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Write at most his_mru bytes to the physical link */ 772706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (len <= dl->physical->link.lcp.his_mru) { 773706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mo = m; 774706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh end = 1; 775706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m_settype(mo, MB_MPOUT); 776706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { 777706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* It's > his_mru, chop the packet (`m') into bits */ 778706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mo = m_get(dl->physical->link.lcp.his_mru, MB_MPOUT); 779706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh len -= mo->m_len; 780706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m = mbuf_Read(m, MBUF_CTOP(mo), mo->m_len); 781706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 782706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp_Output(mp, bundle, &dl->physical->link, mo, begin, end); 783706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh begin = 0; 784706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 785706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 786706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!end) { 787706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh nlinks--; 788706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dl = dl->next; 789706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!dl) { 790706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh dl = bundle->links; 791706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh thislink = 0; 792706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else 793706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh thislink++; 794706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 795706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 796706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 797706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 798706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->out.link = thislink; /* Start here next time */ 799706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 800706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return total; 801706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 802706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 803706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehint 804706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_SetDatalinkBandwidth(struct cmdargs const *arg) 805706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 806706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int val; 807706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 808706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (arg->argc != arg->argn+1) 809706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return -1; 810706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 811706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh val = atoi(arg->argv[arg->argn]); 812706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (val <= 0) { 813706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogWARN, "The link bandwidth must be greater than zero\n"); 814706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 1; 815706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 816706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh arg->cx->mp.bandwidth = val; 817706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 818706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (arg->cx->state == DATALINK_OPEN) 819706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bundle_CalculateBandwidth(arg->bundle); 820706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 821706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 0; 822706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 823706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 824706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehint 825706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_ShowStatus(struct cmdargs const *arg) 826706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 827706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mp *mp = &arg->bundle->ncp.mp; 828706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 829706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, "Multilink is %sactive\n", mp->active ? "" : "in"); 830706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (mp->active) { 831706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mbuf *m, *lm; 832706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int bufs = 0; 833706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 834706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh lm = NULL; 835706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, "Socket: %s\n", 836706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->server.socket.sun_path); 837706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh for (m = mp->inbufs; m; m = m->m_nextpkt) { 838706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bufs++; 839706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh lm = m; 840706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 841706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, "Pending frags: %d", bufs); 842706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (bufs) { 843706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mp_header mh; 844706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh unsigned long first, last; 845706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 846706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh first = mp_ReadHeader(mp, mp->inbufs, &mh) ? mh.seq : 0; 847706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh last = mp_ReadHeader(mp, lm, &mh) ? mh.seq : 0; 848706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " (Have %lu - %lu, want %lu, lowest %lu)\n", 849706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh first, last, (unsigned long)mp->seq.next_in, 850706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh (unsigned long)mp->seq.min_in); 851706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " First has %sbegin bit and " 852706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh "%send bit", mh.begin ? "" : "no ", mh.end ? "" : "no "); 853706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 854706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, "\n"); 855706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 856706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 857706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, "\nMy Side:\n"); 858706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (mp->active) { 859706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " Output SEQ: %u\n", mp->out.seq); 860706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " MRRU: %u\n", mp->local_mrru); 861706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " Short Seq: %s\n", 862706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->local_is12bit ? "on" : "off"); 863706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 864706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " Discriminator: %s\n", 865706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp_Enddisc(mp->cfg.enddisc.class, mp->cfg.enddisc.address, 866706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.enddisc.len)); 867706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 868706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, "\nHis Side:\n"); 869706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (mp->active) { 870706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " Auth Name: %s\n", mp->peer.authname); 871706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " Input SEQ: %u\n", mp->seq.next_in); 872706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " MRRU: %u\n", mp->peer_mrru); 873706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " Short Seq: %s\n", 874706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->peer_is12bit ? "on" : "off"); 875706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 876706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " Discriminator: %s\n", 877706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp_Enddisc(mp->peer.enddisc.class, mp->peer.enddisc.address, 878706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->peer.enddisc.len)); 879706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 880706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, "\nDefaults:\n"); 881706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 882706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " MRRU: "); 883706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (mp->cfg.mrru) 884706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, "%d (multilink enabled)\n", mp->cfg.mrru); 885706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh else 886706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, "disabled\n"); 887706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " Short Seq: %s\n", 888706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh command_ShowNegval(mp->cfg.shortseq)); 889706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " Discriminator: %s\n", 890706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh command_ShowNegval(mp->cfg.negenddisc)); 891706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh prompt_Printf(arg->prompt, " AutoLoad: min %d%%, max %d%%," 892706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh " period %d secs\n", mp->cfg.autoload.min, 893706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.autoload.max, mp->cfg.autoload.period); 894706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 895706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 0; 896706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 897706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 898706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehconst char * 899706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_Enddisc(u_char c, const char *address, size_t len) 900706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 901706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh static char result[100]; /* Used immediately after it's returned */ 902706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh unsigned f, header; 903706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 904706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (c) { 905706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ENDDISC_NULL: 906706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh sprintf(result, "Null Class"); 907706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 908706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 909706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ENDDISC_LOCAL: 910706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh snprintf(result, sizeof result, "Local Addr: %.*s", (int)len, 911706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh address); 912706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 913706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 914706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ENDDISC_IP: 915706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (len == 4) 916706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh snprintf(result, sizeof result, "IP %s", 917706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh inet_ntoa(*(const struct in_addr *)address)); 918706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh else 919706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh sprintf(result, "IP[%zd] ???", len); 920706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 921706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 922706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ENDDISC_MAC: 923706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (len == 6) { 924706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh const u_char *m = (const u_char *)address; 925706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh snprintf(result, sizeof result, "MAC %02x:%02x:%02x:%02x:%02x:%02x", 926706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh m[0], m[1], m[2], m[3], m[4], m[5]); 927706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else 928706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh sprintf(result, "MAC[%zd] ???", len); 929706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 930706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 931706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ENDDISC_MAGIC: 932706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh sprintf(result, "Magic: 0x"); 933706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh header = strlen(result); 934706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (len + header + 1 > sizeof result) 935706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh len = sizeof result - header - 1; 936706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh for (f = 0; f < len; f++) 937706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh sprintf(result + header + 2 * f, "%02x", address[f]); 938706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 939706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 940706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case ENDDISC_PSN: 941706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh snprintf(result, sizeof result, "PSN: %.*s", (int)len, address); 942706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 943706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 944706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh default: 945706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh sprintf(result, "%d: ", (int)c); 946706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh header = strlen(result); 947706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (len + header + 1 > sizeof result) 948706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh len = sizeof result - header - 1; 949706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh for (f = 0; f < len; f++) 950706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh sprintf(result + header + 2 * f, "%02x", address[f]); 951706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 952706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 953706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return result; 954706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 955706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 956706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehint 957706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_SetEnddisc(struct cmdargs const *arg) 958706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 959706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mp *mp = &arg->bundle->ncp.mp; 960706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct in_addr addr; 961706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 962706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh switch (bundle_Phase(arg->bundle)) { 963706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case PHASE_DEAD: 964706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 965706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh case PHASE_ESTABLISH: 966706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Make sure none of our links are DATALINK_LCP or greater */ 967706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (bundle_HighestState(arg->bundle) >= DATALINK_LCP) { 968706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogWARN, "enddisc: Only changable before" 969706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh " LCP negotiations\n"); 970706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 1; 971706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 972706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh break; 973706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh default: 974706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogWARN, "enddisc: Only changable at phase DEAD/ESTABLISH\n"); 975706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 1; 976706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 977706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 978706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (arg->argc == arg->argn) { 979706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.enddisc.class = 0; 980706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *mp->cfg.enddisc.address = '\0'; 981706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.enddisc.len = 0; 982706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else if (arg->argc > arg->argn) { 983706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!strcasecmp(arg->argv[arg->argn], "label")) { 984706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.enddisc.class = ENDDISC_LOCAL; 985706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh strcpy(mp->cfg.enddisc.address, arg->bundle->cfg.label); 986706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.enddisc.len = strlen(mp->cfg.enddisc.address); 987706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else if (!strcasecmp(arg->argv[arg->argn], "ip")) { 988706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (arg->bundle->ncp.ipcp.my_ip.s_addr == INADDR_ANY) 989706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ncprange_getip4addr(&arg->bundle->ncp.ipcp.cfg.my_range, &addr); 990706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh else 991706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh addr = arg->bundle->ncp.ipcp.my_ip; 992706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcpy(mp->cfg.enddisc.address, &addr.s_addr, sizeof addr.s_addr); 993706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.enddisc.class = ENDDISC_IP; 994706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.enddisc.len = sizeof arg->bundle->ncp.ipcp.my_ip.s_addr; 995706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else if (!strcasecmp(arg->argv[arg->argn], "mac")) { 996706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct sockaddr_dl hwaddr; 997706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 998706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (arg->bundle->ncp.ipcp.my_ip.s_addr == INADDR_ANY) 999706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh ncprange_getip4addr(&arg->bundle->ncp.ipcp.cfg.my_range, &addr); 1000706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh else 1001706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh addr = arg->bundle->ncp.ipcp.my_ip; 1002706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1003706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (arp_EtherAddr(addr, &hwaddr, 1)) { 1004706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.enddisc.class = ENDDISC_MAC; 1005706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memcpy(mp->cfg.enddisc.address, hwaddr.sdl_data + hwaddr.sdl_nlen, 1006706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh hwaddr.sdl_alen); 1007706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.enddisc.len = hwaddr.sdl_alen; 1008706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { 1009706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogWARN, "set enddisc: Can't locate MAC address for %s\n", 1010706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh inet_ntoa(addr)); 1011706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 4; 1012706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1013706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else if (!strcasecmp(arg->argv[arg->argn], "magic")) { 1014706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int f; 1015706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1016706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh randinit(); 1017706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh for (f = 0; f < 20; f += sizeof(long)) 1018706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *(long *)(mp->cfg.enddisc.address + f) = random(); 1019706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.enddisc.class = ENDDISC_MAGIC; 1020706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.enddisc.len = 20; 1021706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else if (!strcasecmp(arg->argv[arg->argn], "psn")) { 1022706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (arg->argc > arg->argn+1) { 1023706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.enddisc.class = ENDDISC_PSN; 1024706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh strcpy(mp->cfg.enddisc.address, arg->argv[arg->argn+1]); 1025706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp->cfg.enddisc.len = strlen(mp->cfg.enddisc.address); 1026706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { 1027706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogWARN, "PSN endpoint requires additional data\n"); 1028706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 5; 1029706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1030706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else { 1031706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogWARN, "%s: Unrecognised endpoint type\n", 1032706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh arg->argv[arg->argn]); 1033706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 6; 1034706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1035706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1036706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1037706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 0; 1038706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1039706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1040706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int 1041706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmpserver_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, 1042706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int *n) 1043706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1044706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mpserver *s = descriptor2mpserver(d); 1045706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int result; 1046706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1047706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh result = 0; 1048706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (s->send.dl != NULL) { 1049706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* We've connect()ed */ 1050706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (!link_QueueLen(&s->send.dl->physical->link) && 1051706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh !s->send.dl->physical->out) { 1052706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Only send if we've transmitted all our data (i.e. the ConfigAck) */ 1053706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh result -= datalink_RemoveFromSet(s->send.dl, r, w, e); 1054706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bundle_SendDatalink(s->send.dl, s->fd, &s->socket); 1055706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh s->send.dl = NULL; 1056706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh s->fd = -1; 1057706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else 1058706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Never read from a datalink that's on death row ! */ 1059706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh result -= datalink_RemoveFromSet(s->send.dl, r, NULL, NULL); 1060706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else if (r && s->fd >= 0) { 1061706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (*n < s->fd + 1) 1062706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh *n = s->fd + 1; 1063706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh FD_SET(s->fd, r); 1064706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogTIMER, "mp: fdset(r) %d\n", s->fd); 1065706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh result++; 1066706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1067706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return result; 1068706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1069706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1070706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int 1071706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmpserver_IsSet(struct fdescriptor *d, const fd_set *fdset) 1072706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1073706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mpserver *s = descriptor2mpserver(d); 1074706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return s->fd >= 0 && FD_ISSET(s->fd, fdset); 1075706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1076706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1077706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic void 1078706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmpserver_Read(struct fdescriptor *d, struct bundle *bundle, 1079706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh const fd_set *fdset __unused) 1080706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1081706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh struct mpserver *s = descriptor2mpserver(d); 1082706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1083706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bundle_ReceiveDatalink(bundle, s->fd); 1084706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1085706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1086706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehstatic int 1087706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmpserver_Write(struct fdescriptor *d __unused, struct bundle *bundle __unused, 1088706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh const fd_set *fdset __unused) 1089706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1090706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* We never want to write here ! */ 1091706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogALERT, "mpserver_Write: Internal error: Bad call !\n"); 1092706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return 0; 1093706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1094706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1095706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 1096706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmpserver_Init(struct mpserver *s) 1097706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1098706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh s->desc.type = MPSERVER_DESCRIPTOR; 1099706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh s->desc.UpdateSet = mpserver_UpdateSet; 1100706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh s->desc.IsSet = mpserver_IsSet; 1101706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh s->desc.Read = mpserver_Read; 1102706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh s->desc.Write = mpserver_Write; 1103706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh s->send.dl = NULL; 1104706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh s->fd = -1; 1105706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memset(&s->socket, '\0', sizeof s->socket); 1106706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1107706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1108706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehint 1109706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmpserver_Open(struct mpserver *s, struct peerid *peer) 1110706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1111706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh int f, l; 1112706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mode_t mask; 1113706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1114706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (s->fd != -1) { 1115706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogALERT, "Internal error ! mpserver already open\n"); 1116706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mpserver_Close(s); 1117706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1118706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1119706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh l = snprintf(s->socket.sun_path, sizeof s->socket.sun_path, "%sppp-%s-%02x-", 1120706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh _PATH_VARRUN, peer->authname, peer->enddisc.class); 1121706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (l < 0) { 1122706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogERROR, "mpserver: snprintf(): %s\n", strerror(errno)); 1123706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return MPSERVER_FAILED; 1124706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1125706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1126706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh for (f = 0; 1127706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh f < peer->enddisc.len && (size_t)l < sizeof s->socket.sun_path - 2; 1128706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh f++) { 1129706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh snprintf(s->socket.sun_path + l, sizeof s->socket.sun_path - l, 1130706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh "%02x", *(u_char *)(peer->enddisc.address+f)); 1131706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh l += 2; 1132706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1133706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1134706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh s->socket.sun_family = AF_LOCAL; 1135706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh s->socket.sun_len = sizeof s->socket; 1136706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh s->fd = ID0socket(PF_LOCAL, SOCK_DGRAM, 0); 1137706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (s->fd < 0) { 1138706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogERROR, "mpserver: socket(): %s\n", strerror(errno)); 1139706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return MPSERVER_FAILED; 1140706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1141706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1142706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh setsockopt(s->fd, SOL_SOCKET, SO_REUSEADDR, (struct sockaddr *)&s->socket, 1143706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh sizeof s->socket); 1144706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mask = umask(0177); 1145706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1146706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* 1147706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * Try to bind the socket. If we succeed we play server, if we fail 1148706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh * we connect() and hand the link off. 1149706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh */ 1150706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1151706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (ID0bind_un(s->fd, &s->socket) < 0) { 1152706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (errno != EADDRINUSE) { 1153706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogPHASE, "mpserver: can't create bundle socket %s (%s)\n", 1154706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh s->socket.sun_path, strerror(errno)); 1155706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh umask(mask); 1156706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh close(s->fd); 1157706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh s->fd = -1; 1158706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return MPSERVER_FAILED; 1159706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1160706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1161706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* So we're the sender */ 1162706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh umask(mask); 1163706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (ID0connect_un(s->fd, &s->socket) < 0) { 1164706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogPHASE, "mpserver: can't connect to bundle socket %s (%s)\n", 1165706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh s->socket.sun_path, strerror(errno)); 1166706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (errno == ECONNREFUSED) 1167706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogPHASE, " The previous server died badly !\n"); 1168706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh close(s->fd); 1169706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh s->fd = -1; 1170706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return MPSERVER_FAILED; 1171706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1172706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1173706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* Donate our link to the other guy */ 1174706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return MPSERVER_CONNECTED; 1175706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1176706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1177706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return MPSERVER_LISTENING; 1178706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1179706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1180706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 1181706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmpserver_Close(struct mpserver *s) 1182706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1183706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (s->send.dl != NULL) { 1184706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh bundle_SendDatalink(s->send.dl, s->fd, &s->socket); 1185706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh s->send.dl = NULL; 1186706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh s->fd = -1; 1187706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } else if (s->fd >= 0) { 1188706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh close(s->fd); 1189706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (ID0unlink(s->socket.sun_path) == -1) 1190706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh log_Printf(LogERROR, "%s: Failed to remove: %s\n", s->socket.sun_path, 1191706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh strerror(errno)); 1192706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh memset(&s->socket, '\0', sizeof s->socket); 1193706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh s->fd = -1; 1194706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh } 1195706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1196706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1197706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehvoid 1198706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_LinkLost(struct mp *mp, struct datalink *dl) 1199706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1200706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh if (mp->seq.min_in == dl->mp.seq) 1201706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh /* We've lost the link that's holding everything up ! */ 1202706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh mp_Assemble(mp, NULL, NULL); 1203706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1204706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh 1205706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehsize_t 1206706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yehmp_QueueLen(struct mp *mp) 1207706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh{ 1208706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh return link_QueueLen(&mp->link); 1209706e567fc5ff6b79738a5f470e5aa7b2cae76459Chia-chi Yeh} 1210