Next round of fixing all kinds of spelling mistakes.
[dragonfly.git] / usr.sbin / ppp / mp.c
1 /*-
2  * Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD: src/usr.sbin/ppp/mp.c,v 1.36.2.9 2002/09/01 02:12:28 brian Exp $
27  * $DragonFly: src/usr.sbin/ppp/mp.c,v 1.3 2007/05/17 08:19:03 swildner Exp $
28  */
29
30 #include <sys/param.h>
31 #include <netinet/in.h>
32 #include <netinet/in_systm.h>
33 #include <netinet/ip.h>
34 #include <arpa/inet.h>
35 #include <net/if_dl.h>
36 #include <sys/socket.h>
37 #include <sys/un.h>
38
39 #include <errno.h>
40 #include <paths.h>
41 #include <stdarg.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <sys/stat.h>
46 #include <termios.h>
47 #include <unistd.h>
48
49 #include "layer.h"
50 #ifndef NONAT
51 #include "nat_cmd.h"
52 #endif
53 #include "vjcomp.h"
54 #include "ua.h"
55 #include "defs.h"
56 #include "command.h"
57 #include "mbuf.h"
58 #include "log.h"
59 #include "timer.h"
60 #include "fsm.h"
61 #include "iplist.h"
62 #include "throughput.h"
63 #include "slcompress.h"
64 #include "lqr.h"
65 #include "hdlc.h"
66 #include "ncpaddr.h"
67 #include "ipcp.h"
68 #include "auth.h"
69 #include "lcp.h"
70 #include "async.h"
71 #include "ccp.h"
72 #include "link.h"
73 #include "descriptor.h"
74 #include "physical.h"
75 #include "chat.h"
76 #include "proto.h"
77 #include "filter.h"
78 #include "mp.h"
79 #include "chap.h"
80 #include "cbcp.h"
81 #include "datalink.h"
82 #ifndef NORADIUS
83 #include "radius.h"
84 #endif
85 #include "ipv6cp.h"
86 #include "ncp.h"
87 #include "bundle.h"
88 #include "prompt.h"
89 #include "id.h"
90 #include "arp.h"
91
92 void
93 peerid_Init(struct peerid *peer)
94 {
95   peer->enddisc.class = 0;
96   *peer->enddisc.address = '\0';
97   peer->enddisc.len = 0;
98   *peer->authname = '\0';
99 }
100
101 int
102 peerid_Equal(const struct peerid *p1, const struct peerid *p2)
103 {
104   return !strcmp(p1->authname, p2->authname) &&
105          p1->enddisc.class == p2->enddisc.class &&
106          p1->enddisc.len == p2->enddisc.len &&
107          !memcmp(p1->enddisc.address, p2->enddisc.address, p1->enddisc.len);
108 }
109
110 static u_int32_t
111 inc_seq(unsigned is12bit, u_int32_t seq)
112 {
113   seq++;
114   if (is12bit) {
115     if (seq & 0xfffff000)
116       seq = 0;
117   } else if (seq & 0xff000000)
118     seq = 0;
119   return seq;
120 }
121
122 static int
123 isbefore(unsigned is12bit, u_int32_t seq1, u_int32_t seq2)
124 {
125   u_int32_t max = (is12bit ? 0xfff : 0xffffff) - 0x200;
126
127   if (seq1 > max) {
128     if (seq2 < 0x200 || seq2 > seq1)
129       return 1;
130   } else if ((seq1 > 0x200 || seq2 <= max) && seq1 < seq2)
131     return 1;
132
133   return 0;
134 }
135
136 static int
137 mp_ReadHeader(struct mp *mp, struct mbuf *m, struct mp_header *header)
138 {
139   if (mp->local_is12bit) {
140     u_int16_t val;
141
142     ua_ntohs(MBUF_CTOP(m), &val);
143     if (val & 0x3000) {
144       log_Printf(LogWARN, "Oops - MP header without required zero bits\n");
145       return 0;
146     }
147     header->begin = val & 0x8000 ? 1 : 0;
148     header->end = val & 0x4000 ? 1 : 0;
149     header->seq = val & 0x0fff;
150     return 2;
151   } else {
152     ua_ntohl(MBUF_CTOP(m), &header->seq);
153     if (header->seq & 0x3f000000) {
154       log_Printf(LogWARN, "Oops - MP header without required zero bits\n");
155       return 0;
156     }
157     header->begin = header->seq & 0x80000000 ? 1 : 0;
158     header->end = header->seq & 0x40000000 ? 1 : 0;
159     header->seq &= 0x00ffffff;
160     return 4;
161   }
162 }
163
164 static void
165 mp_LayerStart(void *v, struct fsm *fp)
166 {
167   /* The given FSM (ccp) is about to start up ! */
168 }
169
170 static void
171 mp_LayerUp(void *v, struct fsm *fp)
172 {
173   /* The given fsm (ccp) is now up */
174
175   bundle_CalculateBandwidth(fp->bundle);        /* Against ccp_MTUOverhead */
176 }
177
178 static void
179 mp_LayerDown(void *v, struct fsm *fp)
180 {
181   /* The given FSM (ccp) has been told to come down */
182 }
183
184 static void
185 mp_LayerFinish(void *v, struct fsm *fp)
186 {
187   /* The given fsm (ccp) is now down */
188   if (fp->state == ST_CLOSED && fp->open_mode == OPEN_PASSIVE)
189     fsm_Open(fp);               /* CCP goes to ST_STOPPED */
190 }
191
192 static void
193 mp_UpDown(void *v)
194 {
195   struct mp *mp = (struct mp *)v;
196   int percent;
197
198   percent = MAX(mp->link.stats.total.in.OctetsPerSecond,
199                 mp->link.stats.total.out.OctetsPerSecond) * 800 /
200             mp->bundle->bandwidth;
201   if (percent >= mp->cfg.autoload.max) {
202     log_Printf(LogDEBUG, "%d%% saturation - bring a link up ?\n", percent);
203     bundle_AutoAdjust(mp->bundle, percent, AUTO_UP);
204   } else if (percent <= mp->cfg.autoload.min) {
205     log_Printf(LogDEBUG, "%d%% saturation - bring a link down ?\n", percent);
206     bundle_AutoAdjust(mp->bundle, percent, AUTO_DOWN);
207   }
208 }
209
210 void
211 mp_StopAutoloadTimer(struct mp *mp)
212 {
213   throughput_stop(&mp->link.stats.total);
214 }
215
216 void
217 mp_CheckAutoloadTimer(struct mp *mp)
218 {
219   if (mp->link.stats.total.SamplePeriod != mp->cfg.autoload.period) {
220     throughput_destroy(&mp->link.stats.total);
221     throughput_init(&mp->link.stats.total, mp->cfg.autoload.period);
222     throughput_callback(&mp->link.stats.total, mp_UpDown, mp);
223   }
224
225   if (bundle_WantAutoloadTimer(mp->bundle))
226     throughput_start(&mp->link.stats.total, "MP throughput", 1);
227   else
228     mp_StopAutoloadTimer(mp);
229 }
230
231 void
232 mp_RestartAutoloadTimer(struct mp *mp)
233 {
234   if (mp->link.stats.total.SamplePeriod != mp->cfg.autoload.period)
235     mp_CheckAutoloadTimer(mp);
236   else
237     throughput_clear(&mp->link.stats.total, THROUGHPUT_OVERALL, NULL);
238 }
239
240 void
241 mp_Init(struct mp *mp, struct bundle *bundle)
242 {
243   mp->peer_is12bit = mp->local_is12bit = 0;
244   mp->peer_mrru = mp->local_mrru = 0;
245
246   peerid_Init(&mp->peer);
247
248   mp->out.seq = 0;
249   mp->out.link = 0;
250   mp->out.af = AF_INET;
251   mp->seq.min_in = 0;
252   mp->seq.next_in = 0;
253   mp->inbufs = NULL;
254   mp->bundle = bundle;
255
256   mp->link.type = LOGICAL_LINK;
257   mp->link.name = "mp";
258   mp->link.len = sizeof *mp;
259
260   mp->cfg.autoload.period = SAMPLE_PERIOD;
261   mp->cfg.autoload.min = mp->cfg.autoload.max = 0;
262   throughput_init(&mp->link.stats.total, mp->cfg.autoload.period);
263   throughput_callback(&mp->link.stats.total, mp_UpDown, mp);
264   mp->link.stats.parent = NULL;
265   mp->link.stats.gather = 0;    /* Let the physical links gather stats */
266   memset(mp->link.Queue, '\0', sizeof mp->link.Queue);
267   memset(mp->link.proto_in, '\0', sizeof mp->link.proto_in);
268   memset(mp->link.proto_out, '\0', sizeof mp->link.proto_out);
269
270   mp->fsmp.LayerStart = mp_LayerStart;
271   mp->fsmp.LayerUp = mp_LayerUp;
272   mp->fsmp.LayerDown = mp_LayerDown;
273   mp->fsmp.LayerFinish = mp_LayerFinish;
274   mp->fsmp.object = mp;
275
276   mpserver_Init(&mp->server);
277
278   mp->cfg.mrru = 0;
279   mp->cfg.shortseq = NEG_ENABLED|NEG_ACCEPTED;
280   mp->cfg.negenddisc = NEG_ENABLED|NEG_ACCEPTED;
281   mp->cfg.enddisc.class = 0;
282   *mp->cfg.enddisc.address = '\0';
283   mp->cfg.enddisc.len = 0;
284
285   lcp_Init(&mp->link.lcp, mp->bundle, &mp->link, NULL);
286   ccp_Init(&mp->link.ccp, mp->bundle, &mp->link, &mp->fsmp);
287
288   link_EmptyStack(&mp->link);
289   link_Stack(&mp->link, &protolayer);
290   link_Stack(&mp->link, &ccplayer);
291   link_Stack(&mp->link, &vjlayer);
292 #ifndef NONAT
293   link_Stack(&mp->link, &natlayer);
294 #endif
295 }
296
297 int
298 mp_Up(struct mp *mp, struct datalink *dl)
299 {
300   struct lcp *lcp = &dl->physical->link.lcp;
301
302   if (mp->active) {
303     /* We're adding a link - do a last validation on our parameters */
304     if (!peerid_Equal(&dl->peer, &mp->peer)) {
305       log_Printf(LogPHASE, "%s: Inappropriate peer !\n", dl->name);
306       log_Printf(LogPHASE, "  Attached to peer %s/%s\n", mp->peer.authname,
307                  mp_Enddisc(mp->peer.enddisc.class, mp->peer.enddisc.address,
308                             mp->peer.enddisc.len));
309       log_Printf(LogPHASE, "  New link is peer %s/%s\n", dl->peer.authname,
310                  mp_Enddisc(dl->peer.enddisc.class, dl->peer.enddisc.address,
311                             dl->peer.enddisc.len));
312       return MP_FAILED;
313     }
314     if (mp->local_mrru != lcp->want_mrru ||
315         mp->peer_mrru != lcp->his_mrru ||
316         mp->local_is12bit != lcp->want_shortseq ||
317         mp->peer_is12bit != lcp->his_shortseq) {
318       log_Printf(LogPHASE, "%s: Invalid MRRU/SHORTSEQ MP parameters !\n",
319                 dl->name);
320       return MP_FAILED;
321     }
322     return MP_ADDED;
323   } else {
324     /* First link in multilink mode */
325
326     mp->local_mrru = lcp->want_mrru;
327     mp->peer_mrru = lcp->his_mrru;
328     mp->local_is12bit = lcp->want_shortseq;
329     mp->peer_is12bit = lcp->his_shortseq;
330     mp->peer = dl->peer;
331
332     throughput_destroy(&mp->link.stats.total);
333     throughput_init(&mp->link.stats.total, mp->cfg.autoload.period);
334     throughput_callback(&mp->link.stats.total, mp_UpDown, mp);
335     memset(mp->link.Queue, '\0', sizeof mp->link.Queue);
336     memset(mp->link.proto_in, '\0', sizeof mp->link.proto_in);
337     memset(mp->link.proto_out, '\0', sizeof mp->link.proto_out);
338
339     /* Tell the link who it belongs to */
340     dl->physical->link.stats.parent = &mp->link.stats.total;
341
342     mp->out.seq = 0;
343     mp->out.link = 0;
344     mp->out.af = AF_INET;
345     mp->seq.min_in = 0;
346     mp->seq.next_in = 0;
347
348     /*
349      * Now we create our server socket.
350      * If it already exists, join it.  Otherwise, create and own it
351      */
352     switch (mpserver_Open(&mp->server, &mp->peer)) {
353     case MPSERVER_CONNECTED:
354       log_Printf(LogPHASE, "mp: Transfer link on %s\n",
355                 mp->server.socket.sun_path);
356       mp->server.send.dl = dl;          /* Defer 'till it's safe to send */
357       return MP_LINKSENT;
358     case MPSERVER_FAILED:
359       return MP_FAILED;
360     case MPSERVER_LISTENING:
361       log_Printf(LogPHASE, "mp: Listening on %s\n", mp->server.socket.sun_path);
362       log_Printf(LogPHASE, "    First link: %s\n", dl->name);
363
364       /* Re-point our NCP layers at our MP link */
365       ncp_SetLink(&mp->bundle->ncp, &mp->link);
366
367       /* Our lcp's already up 'cos of the NULL parent */
368       if (ccp_SetOpenMode(&mp->link.ccp)) {
369         fsm_Up(&mp->link.ccp.fsm);
370         fsm_Open(&mp->link.ccp.fsm);
371       }
372
373       mp->active = 1;
374       break;
375     }
376   }
377
378   return MP_UP;
379 }
380
381 void
382 mp_Down(struct mp *mp)
383 {
384   if (mp->active) {
385     struct mbuf *next;
386
387     /* Stop that ! */
388     mp_StopAutoloadTimer(mp);
389
390     /* Don't want any more of these */
391     mpserver_Close(&mp->server);
392
393     /* CCP goes down with a bang */
394     fsm2initial(&mp->link.ccp.fsm);
395
396     /* Received fragments go in the bit-bucket */
397     while (mp->inbufs) {
398       next = mp->inbufs->m_nextpkt;
399       m_freem(mp->inbufs);
400       mp->inbufs = next;
401     }
402
403     peerid_Init(&mp->peer);
404     mp->active = 0;
405   }
406 }
407
408 void
409 mp_linkInit(struct mp_link *mplink)
410 {
411   mplink->seq = 0;
412   mplink->bandwidth = 0;
413 }
414
415 static void
416 mp_Assemble(struct mp *mp, struct mbuf *m, struct physical *p)
417 {
418   struct mp_header mh, h;
419   struct mbuf *q, *last;
420   int32_t seq;
421
422   /*
423    * When `m' and `p' are NULL, it means our oldest link has gone down.
424    * We want to determine a new min, and process any intermediate stuff
425    * as normal
426    */
427
428   if (m && mp_ReadHeader(mp, m, &mh) == 0) {
429     m_freem(m);
430     return;
431   }
432
433   if (p) {
434     seq = p->dl->mp.seq;
435     p->dl->mp.seq = mh.seq;
436   } else
437     seq = mp->seq.min_in;
438
439   if (mp->seq.min_in == seq) {
440     /*
441      * We've received new data on the link that has our min (oldest) seq.
442      * Figure out which link now has the smallest (oldest) seq.
443      */
444     struct datalink *dl;
445
446     mp->seq.min_in = (u_int32_t)-1;
447     for (dl = mp->bundle->links; dl; dl = dl->next)
448       if (dl->state == DATALINK_OPEN &&
449           (mp->seq.min_in == -1 ||
450            isbefore(mp->local_is12bit, dl->mp.seq, mp->seq.min_in)))
451         mp->seq.min_in = dl->mp.seq;
452   }
453
454   /*
455    * Now process as many of our fragments as we can, adding our new
456    * fragment in as we go, and ordering with the oldest at the top of
457    * the queue.
458    */
459
460   last = NULL;
461   seq = mp->seq.next_in;
462   q = mp->inbufs;
463   while (q || m) {
464     if (!q) {
465       if (last)
466         last->m_nextpkt = m;
467       else
468         mp->inbufs = m;
469       q = m;
470       m = NULL;
471       h = mh;
472     } else {
473       mp_ReadHeader(mp, q, &h);
474
475       if (m && isbefore(mp->local_is12bit, mh.seq, h.seq)) {
476         /* Our received fragment fits in before this one, so link it in */
477         if (last)
478           last->m_nextpkt = m;
479         else
480           mp->inbufs = m;
481         m->m_nextpkt = q;
482         q = m;
483         h = mh;
484         m = NULL;
485       }
486     }
487
488     if (h.seq != seq) {
489       /* we're missing something :-( */
490       if (isbefore(mp->local_is12bit, seq, mp->seq.min_in)) {
491         /* we're never gonna get it */
492         struct mbuf *next;
493
494         /* Zap all older fragments */
495         while (mp->inbufs != q) {
496           log_Printf(LogDEBUG, "Drop frag\n");
497           next = mp->inbufs->m_nextpkt;
498           m_freem(mp->inbufs);
499           mp->inbufs = next;
500         }
501
502         /*
503          * Zap everything until the next `end' fragment OR just before
504          * the next `begin' fragment OR 'till seq.min_in - whichever
505          * comes first.
506          */
507         do {
508           mp_ReadHeader(mp, mp->inbufs, &h);
509           if (h.begin) {
510             /* We might be able to process this ! */
511             h.seq--;  /* We're gonna look for fragment with h.seq+1 */
512             break;
513           }
514           next = mp->inbufs->m_nextpkt;
515           log_Printf(LogDEBUG, "Drop frag %u\n", h.seq);
516           m_freem(mp->inbufs);
517           mp->inbufs = next;
518         } while (mp->inbufs && (isbefore(mp->local_is12bit, mp->seq.min_in,
519                                          h.seq) || h.end));
520
521         /*
522          * Continue processing things from here.
523          * This deals with the possibility that we received a fragment
524          * on the slowest link that invalidates some of our data (because
525          * of the hole at `q'), but where there are subsequent `whole'
526          * packets that have already been received.
527          */
528
529         mp->seq.next_in = seq = inc_seq(mp->local_is12bit, h.seq);
530         last = NULL;
531         q = mp->inbufs;
532       } else
533         /* we may still receive the missing fragment */
534         break;
535     } else if (h.end) {
536       /* We've got something, reassemble */
537       struct mbuf **frag = &q;
538       int len;
539       u_long first = -1;
540
541       do {
542         *frag = mp->inbufs;
543         mp->inbufs = mp->inbufs->m_nextpkt;
544         len = mp_ReadHeader(mp, *frag, &h);
545         if (first == -1)
546           first = h.seq;
547         if (frag == &q && !h.begin) {
548           log_Printf(LogWARN, "Oops - MP frag %lu should have a begin flag\n",
549                     (u_long)h.seq);
550           m_freem(q);
551           q = NULL;
552         } else if (frag != &q && h.begin) {
553           log_Printf(LogWARN, "Oops - MP frag %lu should have an end flag\n",
554                     (u_long)h.seq - 1);
555           /*
556            * Stuff our fragment back at the front of the queue and zap
557            * our half-assembled packet.
558            */
559           (*frag)->m_nextpkt = mp->inbufs;
560           mp->inbufs = *frag;
561           *frag = NULL;
562           m_freem(q);
563           q = NULL;
564           frag = &q;
565           h.end = 0;    /* just in case it's a whole packet */
566         } else {
567           (*frag)->m_offset += len;
568           (*frag)->m_len -= len;
569           (*frag)->m_nextpkt = NULL;
570           do
571             frag = &(*frag)->m_next;
572           while (*frag != NULL);
573         }
574       } while (!h.end);
575
576       if (q) {
577         q = m_pullup(q);
578         log_Printf(LogDEBUG, "MP: Reassembled frags %ld-%lu, length %d\n",
579                    first, (u_long)h.seq, m_length(q));
580         link_PullPacket(&mp->link, MBUF_CTOP(q), q->m_len, mp->bundle);
581         m_freem(q);
582       }
583
584       mp->seq.next_in = seq = inc_seq(mp->local_is12bit, h.seq);
585       last = NULL;
586       q = mp->inbufs;
587     } else {
588       /* Look for the next fragment */
589       seq = inc_seq(mp->local_is12bit, seq);
590       last = q;
591       q = q->m_nextpkt;
592     }
593   }
594
595   if (m) {
596     /* We still have to find a home for our new fragment */
597     last = NULL;
598     for (q = mp->inbufs; q; last = q, q = q->m_nextpkt) {
599       mp_ReadHeader(mp, q, &h);
600       if (isbefore(mp->local_is12bit, mh.seq, h.seq))
601         break;
602     }
603     /* Our received fragment fits in here */
604     if (last)
605       last->m_nextpkt = m;
606     else
607       mp->inbufs = m;
608     m->m_nextpkt = q;
609   }
610 }
611
612 struct mbuf *
613 mp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
614 {
615   struct physical *p = link2physical(l);
616
617   if (!bundle->ncp.mp.active)
618     /* Let someone else deal with it ! */
619     return bp;
620
621   if (p == NULL) {
622     log_Printf(LogWARN, "DecodePacket: Can't do MP inside MP !\n");
623     m_freem(bp);
624   } else {
625     m_settype(bp, MB_MPIN);
626     mp_Assemble(&bundle->ncp.mp, bp, p);
627   }
628
629   return NULL;
630 }
631
632 static void
633 mp_Output(struct mp *mp, struct bundle *bundle, struct link *l,
634           struct mbuf *m, u_int32_t begin, u_int32_t end)
635 {
636   char prepend[4];
637
638   /* Stuff an MP header on the front of our packet and send it */
639
640   if (mp->peer_is12bit) {
641     u_int16_t val;
642
643     val = (begin << 15) | (end << 14) | (u_int16_t)mp->out.seq;
644     ua_htons(&val, prepend);
645     m = m_prepend(m, prepend, 2, 0);
646   } else {
647     u_int32_t val;
648
649     val = (begin << 31) | (end << 30) | (u_int32_t)mp->out.seq;
650     ua_htonl(&val, prepend);
651     m = m_prepend(m, prepend, 4, 0);
652   }
653   if (log_IsKept(LogDEBUG))
654     log_Printf(LogDEBUG, "MP[frag %d]: Send %d bytes on link `%s'\n",
655                mp->out.seq, m_length(m), l->name);
656   mp->out.seq = inc_seq(mp->peer_is12bit, mp->out.seq);
657
658   if (l->ccp.fsm.state != ST_OPENED && ccp_Required(&l->ccp)) {
659     log_Printf(LogPHASE, "%s: Not transmitting... waiting for CCP\n", l->name);
660     return;
661   }
662
663   link_PushPacket(l, m, bundle, LINK_QUEUES(l) - 1, PROTO_MP);
664 }
665
666 int
667 mp_FillPhysicalQueues(struct bundle *bundle)
668 {
669   struct mp *mp = &bundle->ncp.mp;
670   struct datalink *dl, *fdl;
671   size_t total, add, len;
672   int thislink, nlinks, nopenlinks, sendasip;
673   u_int32_t begin, end;
674   struct mbuf *m, *mo;
675   struct link *bestlink;
676
677   thislink = nlinks = nopenlinks = 0;
678   for (fdl = NULL, dl = bundle->links; dl; dl = dl->next) {
679     /* Include non-open links here as mp->out.link will stay more correct */
680     if (!fdl) {
681       if (thislink == mp->out.link)
682         fdl = dl;
683       else
684         thislink++;
685     }
686     nlinks++;
687     if (dl->state == DATALINK_OPEN)
688       nopenlinks++;
689   }
690
691   if (!fdl) {
692     fdl = bundle->links;
693     if (!fdl)
694       return 0;
695     thislink = 0;
696   }
697
698   total = 0;
699   for (dl = fdl; nlinks > 0; dl = dl->next, nlinks--, thislink++) {
700     if (!dl) {
701       dl = bundle->links;
702       thislink = 0;
703     }
704
705     if (dl->state != DATALINK_OPEN)
706       continue;
707
708     if (dl->physical->out)
709       /* this link has suffered a short write.  Let it continue */
710       continue;
711
712     add = link_QueueLen(&dl->physical->link);
713     if (add) {
714       /* this link has got stuff already queued.  Let it continue */
715       total += add;
716       continue;
717     }
718
719     if (!mp_QueueLen(mp)) {
720       int mrutoosmall;
721
722       /*
723        * If there's only a single open link in our bundle and we haven't got
724        * MP level link compression, queue outbound traffic directly via that
725        * link's protocol stack rather than using the MP link.  This results
726        * in the outbound traffic going out as PROTO_IP or PROTO_IPV6 rather
727        * than PROTO_MP.
728        */
729
730       mrutoosmall = 0;
731       sendasip = nopenlinks < 2;
732       if (sendasip) {
733         if (dl->physical->link.lcp.his_mru < mp->peer_mrru) {
734           /*
735            * Actually, forget it.  This test is done against the MRRU rather
736            * than the packet size so that we don't end up sending some data
737            * in MP fragments and some data in PROTO_IP packets.  That's just
738            * too likely to upset some ppp implementations.
739            */
740           mrutoosmall = 1;
741           sendasip = 0;
742         }
743       }
744
745       bestlink = sendasip ? &dl->physical->link : &mp->link;
746       if (!ncp_PushPacket(&bundle->ncp, &mp->out.af, bestlink))
747         break;  /* Nothing else to send */
748
749       if (mrutoosmall)
750         log_Printf(LogDEBUG, "Don't send data as PROTO_IP, MRU < MRRU\n");
751       else if (sendasip)
752         log_Printf(LogDEBUG, "Sending data as PROTO_IP, not PROTO_MP\n");
753
754       if (sendasip) {
755         add = link_QueueLen(&dl->physical->link);
756         if (add) {
757           /* this link has got stuff already queued.  Let it continue */
758           total += add;
759           continue;
760         }
761       }
762     }
763
764     m = link_Dequeue(&mp->link);
765     if (m) {
766       len = m_length(m);
767       begin = 1;
768       end = 0;
769
770       while (!end) {
771         if (dl->state == DATALINK_OPEN) {
772           /* Write at most his_mru bytes to the physical link */
773           if (len <= dl->physical->link.lcp.his_mru) {
774             mo = m;
775             end = 1;
776             m_settype(mo, MB_MPOUT);
777           } else {
778             /* It's > his_mru, chop the packet (`m') into bits */
779             mo = m_get(dl->physical->link.lcp.his_mru, MB_MPOUT);
780             len -= mo->m_len;
781             m = mbuf_Read(m, MBUF_CTOP(mo), mo->m_len);
782           }
783           mp_Output(mp, bundle, &dl->physical->link, mo, begin, end);
784           begin = 0;
785         }
786
787         if (!end) {
788           nlinks--;
789           dl = dl->next;
790           if (!dl) {
791             dl = bundle->links;
792             thislink = 0;
793           } else
794             thislink++;
795         }
796       }
797     }
798   }
799   mp->out.link = thislink;              /* Start here next time */
800
801   return total;
802 }
803
804 int
805 mp_SetDatalinkBandwidth(struct cmdargs const *arg)
806 {
807   int val;
808
809   if (arg->argc != arg->argn+1)
810     return -1;
811
812   val = atoi(arg->argv[arg->argn]);
813   if (val <= 0) {
814     log_Printf(LogWARN, "The link bandwidth must be greater than zero\n");
815     return 1;
816   }
817   arg->cx->mp.bandwidth = val;
818
819   if (arg->cx->state == DATALINK_OPEN)
820     bundle_CalculateBandwidth(arg->bundle);
821
822   return 0;
823 }
824
825 int
826 mp_ShowStatus(struct cmdargs const *arg)
827 {
828   struct mp *mp = &arg->bundle->ncp.mp;
829
830   prompt_Printf(arg->prompt, "Multilink is %sactive\n", mp->active ? "" : "in");
831   if (mp->active) {
832     struct mbuf *m, *lm;
833     int bufs = 0;
834
835     lm = NULL;
836     prompt_Printf(arg->prompt, "Socket:         %s\n",
837                   mp->server.socket.sun_path);
838     for (m = mp->inbufs; m; m = m->m_nextpkt) {
839       bufs++;
840       lm = m;
841     }
842     prompt_Printf(arg->prompt, "Pending frags:  %d", bufs);
843     if (bufs) {
844       struct mp_header mh;
845       unsigned long first, last;
846
847       first = mp_ReadHeader(mp, mp->inbufs, &mh) ? mh.seq : 0;
848       last = mp_ReadHeader(mp, lm, &mh) ? mh.seq : 0;
849       prompt_Printf(arg->prompt, " (Have %lu - %lu, want %lu, lowest %lu)\n",
850                     first, last, (unsigned long)mp->seq.next_in,
851                     (unsigned long)mp->seq.min_in);
852       prompt_Printf(arg->prompt, "                First has %sbegin bit and "
853                     "%send bit", mh.begin ? "" : "no ", mh.end ? "" : "no ");
854     }
855     prompt_Printf(arg->prompt, "\n");
856   }
857
858   prompt_Printf(arg->prompt, "\nMy Side:\n");
859   if (mp->active) {
860     prompt_Printf(arg->prompt, " Output SEQ:    %u\n", mp->out.seq);
861     prompt_Printf(arg->prompt, " MRRU:          %u\n", mp->local_mrru);
862     prompt_Printf(arg->prompt, " Short Seq:     %s\n",
863                   mp->local_is12bit ? "on" : "off");
864   }
865   prompt_Printf(arg->prompt, " Discriminator: %s\n",
866                 mp_Enddisc(mp->cfg.enddisc.class, mp->cfg.enddisc.address,
867                            mp->cfg.enddisc.len));
868
869   prompt_Printf(arg->prompt, "\nHis Side:\n");
870   if (mp->active) {
871     prompt_Printf(arg->prompt, " Auth Name:     %s\n", mp->peer.authname);
872     prompt_Printf(arg->prompt, " Input SEQ:     %u\n", mp->seq.next_in);
873     prompt_Printf(arg->prompt, " MRRU:          %u\n", mp->peer_mrru);
874     prompt_Printf(arg->prompt, " Short Seq:     %s\n",
875                   mp->peer_is12bit ? "on" : "off");
876   }
877   prompt_Printf(arg->prompt,   " Discriminator: %s\n",
878                 mp_Enddisc(mp->peer.enddisc.class, mp->peer.enddisc.address,
879                            mp->peer.enddisc.len));
880
881   prompt_Printf(arg->prompt, "\nDefaults:\n");
882
883   prompt_Printf(arg->prompt, " MRRU:          ");
884   if (mp->cfg.mrru)
885     prompt_Printf(arg->prompt, "%d (multilink enabled)\n", mp->cfg.mrru);
886   else
887     prompt_Printf(arg->prompt, "disabled\n");
888   prompt_Printf(arg->prompt, " Short Seq:     %s\n",
889                   command_ShowNegval(mp->cfg.shortseq));
890   prompt_Printf(arg->prompt, " Discriminator: %s\n",
891                   command_ShowNegval(mp->cfg.negenddisc));
892   prompt_Printf(arg->prompt, " AutoLoad:      min %d%%, max %d%%,"
893                 " period %d secs\n", mp->cfg.autoload.min,
894                 mp->cfg.autoload.max, mp->cfg.autoload.period);
895
896   return 0;
897 }
898
899 const char *
900 mp_Enddisc(u_char c, const char *address, int len)
901 {
902   static char result[100];      /* Used immediately after it's returned */
903   int f, header;
904
905   switch (c) {
906     case ENDDISC_NULL:
907       sprintf(result, "Null Class");
908       break;
909
910     case ENDDISC_LOCAL:
911       snprintf(result, sizeof result, "Local Addr: %.*s", len, address);
912       break;
913
914     case ENDDISC_IP:
915       if (len == 4)
916         snprintf(result, sizeof result, "IP %s",
917                  inet_ntoa(*(const struct in_addr *)address));
918       else
919         sprintf(result, "IP[%d] ???", len);
920       break;
921
922     case ENDDISC_MAC:
923       if (len == 6) {
924         const u_char *m = (const u_char *)address;
925         snprintf(result, sizeof result, "MAC %02x:%02x:%02x:%02x:%02x:%02x",
926                  m[0], m[1], m[2], m[3], m[4], m[5]);
927       } else
928         sprintf(result, "MAC[%d] ???", len);
929       break;
930
931     case ENDDISC_MAGIC:
932       sprintf(result, "Magic: 0x");
933       header = strlen(result);
934       if (len > sizeof result - header - 1)
935         len = sizeof result - header - 1;
936       for (f = 0; f < len; f++)
937         sprintf(result + header + 2 * f, "%02x", address[f]);
938       break;
939
940     case ENDDISC_PSN:
941       snprintf(result, sizeof result, "PSN: %.*s", len, address);
942       break;
943
944      default:
945       sprintf(result, "%d: ", (int)c);
946       header = strlen(result);
947       if (len > sizeof result - header - 1)
948         len = sizeof result - header - 1;
949       for (f = 0; f < len; f++)
950         sprintf(result + header + 2 * f, "%02x", address[f]);
951       break;
952   }
953   return result;
954 }
955
956 int
957 mp_SetEnddisc(struct cmdargs const *arg)
958 {
959   struct mp *mp = &arg->bundle->ncp.mp;
960   struct in_addr addr;
961
962   switch (bundle_Phase(arg->bundle)) {
963     case PHASE_DEAD:
964       break;
965     case PHASE_ESTABLISH:
966       /* Make sure none of our links are DATALINK_LCP or greater */
967       if (bundle_HighestState(arg->bundle) >= DATALINK_LCP) {
968         log_Printf(LogWARN, "enddisc: Only changeable before"
969                    " LCP negotiations\n");
970         return 1;
971       }
972       break;
973     default:
974       log_Printf(LogWARN, "enddisc: Only changeable at phase DEAD/ESTABLISH\n");
975       return 1;
976   }
977
978   if (arg->argc == arg->argn) {
979     mp->cfg.enddisc.class = 0;
980     *mp->cfg.enddisc.address = '\0';
981     mp->cfg.enddisc.len = 0;
982   } else if (arg->argc > arg->argn) {
983     if (!strcasecmp(arg->argv[arg->argn], "label")) {
984       mp->cfg.enddisc.class = ENDDISC_LOCAL;
985       strcpy(mp->cfg.enddisc.address, arg->bundle->cfg.label);
986       mp->cfg.enddisc.len = strlen(mp->cfg.enddisc.address);
987     } else if (!strcasecmp(arg->argv[arg->argn], "ip")) {
988       if (arg->bundle->ncp.ipcp.my_ip.s_addr == INADDR_ANY)
989         ncprange_getip4addr(&arg->bundle->ncp.ipcp.cfg.my_range, &addr);
990       else
991         addr = arg->bundle->ncp.ipcp.my_ip;
992       memcpy(mp->cfg.enddisc.address, &addr.s_addr, sizeof addr.s_addr);
993       mp->cfg.enddisc.class = ENDDISC_IP;
994       mp->cfg.enddisc.len = sizeof arg->bundle->ncp.ipcp.my_ip.s_addr;
995     } else if (!strcasecmp(arg->argv[arg->argn], "mac")) {
996       struct sockaddr_dl hwaddr;
997       int s;
998
999       if (arg->bundle->ncp.ipcp.my_ip.s_addr == INADDR_ANY)
1000         ncprange_getip4addr(&arg->bundle->ncp.ipcp.cfg.my_range, &addr);
1001       else
1002         addr = arg->bundle->ncp.ipcp.my_ip;
1003
1004       s = ID0socket(PF_INET, SOCK_DGRAM, 0);
1005       if (s < 0) {
1006         log_Printf(LogERROR, "set enddisc: socket(): %s\n", strerror(errno));
1007         return 2;
1008       }
1009       if (arp_EtherAddr(s, addr, &hwaddr, 1)) {
1010         mp->cfg.enddisc.class = ENDDISC_MAC;
1011         memcpy(mp->cfg.enddisc.address, hwaddr.sdl_data + hwaddr.sdl_nlen,
1012                hwaddr.sdl_alen);
1013         mp->cfg.enddisc.len = hwaddr.sdl_alen;
1014       } else {
1015         log_Printf(LogWARN, "set enddisc: Can't locate MAC address for %s\n",
1016                   inet_ntoa(addr));
1017         close(s);
1018         return 4;
1019       }
1020       close(s);
1021     } else if (!strcasecmp(arg->argv[arg->argn], "magic")) {
1022       int f;
1023
1024       randinit();
1025       for (f = 0; f < 20; f += sizeof(long))
1026         *(long *)(mp->cfg.enddisc.address + f) = random();
1027       mp->cfg.enddisc.class = ENDDISC_MAGIC;
1028       mp->cfg.enddisc.len = 20;
1029     } else if (!strcasecmp(arg->argv[arg->argn], "psn")) {
1030       if (arg->argc > arg->argn+1) {
1031         mp->cfg.enddisc.class = ENDDISC_PSN;
1032         strcpy(mp->cfg.enddisc.address, arg->argv[arg->argn+1]);
1033         mp->cfg.enddisc.len = strlen(mp->cfg.enddisc.address);
1034       } else {
1035         log_Printf(LogWARN, "PSN endpoint requires additional data\n");
1036         return 5;
1037       }
1038     } else {
1039       log_Printf(LogWARN, "%s: Unrecognised endpoint type\n",
1040                 arg->argv[arg->argn]);
1041       return 6;
1042     }
1043   }
1044
1045   return 0;
1046 }
1047
1048 static int
1049 mpserver_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e,
1050                    int *n)
1051 {
1052   struct mpserver *s = descriptor2mpserver(d);
1053   int result;
1054
1055   result = 0;
1056   if (s->send.dl != NULL) {
1057     /* We've connect()ed */
1058     if (!link_QueueLen(&s->send.dl->physical->link) &&
1059         !s->send.dl->physical->out) {
1060       /* Only send if we've transmitted all our data (i.e. the ConfigAck) */
1061       result -= datalink_RemoveFromSet(s->send.dl, r, w, e);
1062       bundle_SendDatalink(s->send.dl, s->fd, &s->socket);
1063       s->send.dl = NULL;
1064       s->fd = -1;
1065     } else
1066       /* Never read from a datalink that's on death row ! */
1067       result -= datalink_RemoveFromSet(s->send.dl, r, NULL, NULL);
1068   } else if (r && s->fd >= 0) {
1069     if (*n < s->fd + 1)
1070       *n = s->fd + 1;
1071     FD_SET(s->fd, r);
1072     log_Printf(LogTIMER, "mp: fdset(r) %d\n", s->fd);
1073     result++;
1074   }
1075   return result;
1076 }
1077
1078 static int
1079 mpserver_IsSet(struct fdescriptor *d, const fd_set *fdset)
1080 {
1081   struct mpserver *s = descriptor2mpserver(d);
1082   return s->fd >= 0 && FD_ISSET(s->fd, fdset);
1083 }
1084
1085 static void
1086 mpserver_Read(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset)
1087 {
1088   struct mpserver *s = descriptor2mpserver(d);
1089
1090   bundle_ReceiveDatalink(bundle, s->fd);
1091 }
1092
1093 static int
1094 mpserver_Write(struct fdescriptor *d, struct bundle *bundle,
1095                const fd_set *fdset)
1096 {
1097   /* We never want to write here ! */
1098   log_Printf(LogALERT, "mpserver_Write: Internal error: Bad call !\n");
1099   return 0;
1100 }
1101
1102 void
1103 mpserver_Init(struct mpserver *s)
1104 {
1105   s->desc.type = MPSERVER_DESCRIPTOR;
1106   s->desc.UpdateSet = mpserver_UpdateSet;
1107   s->desc.IsSet = mpserver_IsSet;
1108   s->desc.Read = mpserver_Read;
1109   s->desc.Write = mpserver_Write;
1110   s->send.dl = NULL;
1111   s->fd = -1;
1112   memset(&s->socket, '\0', sizeof s->socket);
1113 }
1114
1115 int
1116 mpserver_Open(struct mpserver *s, struct peerid *peer)
1117 {
1118   int f, l;
1119   mode_t mask;
1120
1121   if (s->fd != -1) {
1122     log_Printf(LogALERT, "Internal error !  mpserver already open\n");
1123     mpserver_Close(s);
1124   }
1125
1126   l = snprintf(s->socket.sun_path, sizeof s->socket.sun_path, "%sppp-%s-%02x-",
1127                _PATH_VARRUN, peer->authname, peer->enddisc.class);
1128   if (l < 0) {
1129     log_Printf(LogERROR, "mpserver: snprintf(): %s\n", strerror(errno));
1130     return MPSERVER_FAILED;
1131   }
1132
1133   for (f = 0; f < peer->enddisc.len && l < sizeof s->socket.sun_path - 2; f++) {
1134     snprintf(s->socket.sun_path + l, sizeof s->socket.sun_path - l,
1135              "%02x", *(u_char *)(peer->enddisc.address+f));
1136     l += 2;
1137   }
1138
1139   s->socket.sun_family = AF_LOCAL;
1140   s->socket.sun_len = sizeof s->socket;
1141   s->fd = ID0socket(PF_LOCAL, SOCK_DGRAM, 0);
1142   if (s->fd < 0) {
1143     log_Printf(LogERROR, "mpserver: socket(): %s\n", strerror(errno));
1144     return MPSERVER_FAILED;
1145   }
1146
1147   setsockopt(s->fd, SOL_SOCKET, SO_REUSEADDR, (struct sockaddr *)&s->socket,
1148              sizeof s->socket);
1149   mask = umask(0177);
1150
1151   /*
1152    * Try to bind the socket.  If we succeed we play server, if we fail
1153    * we connect() and hand the link off.
1154    */
1155
1156   if (ID0bind_un(s->fd, &s->socket) < 0) {
1157     if (errno != EADDRINUSE) {
1158       log_Printf(LogPHASE, "mpserver: can't create bundle socket %s (%s)\n",
1159                 s->socket.sun_path, strerror(errno));
1160       umask(mask);
1161       close(s->fd);
1162       s->fd = -1;
1163       return MPSERVER_FAILED;
1164     }
1165
1166     /* So we're the sender */
1167     umask(mask);
1168     if (ID0connect_un(s->fd, &s->socket) < 0) {
1169       log_Printf(LogPHASE, "mpserver: can't connect to bundle socket %s (%s)\n",
1170                 s->socket.sun_path, strerror(errno));
1171       if (errno == ECONNREFUSED)
1172         log_Printf(LogPHASE, "          The previous server died badly !\n");
1173       close(s->fd);
1174       s->fd = -1;
1175       return MPSERVER_FAILED;
1176     }
1177
1178     /* Donate our link to the other guy */
1179     return MPSERVER_CONNECTED;
1180   }
1181
1182   return MPSERVER_LISTENING;
1183 }
1184
1185 void
1186 mpserver_Close(struct mpserver *s)
1187 {
1188   if (s->send.dl != NULL) {
1189     bundle_SendDatalink(s->send.dl, s->fd, &s->socket);
1190     s->send.dl = NULL;
1191     s->fd = -1;
1192   } else if (s->fd >= 0) {
1193     close(s->fd);
1194     if (ID0unlink(s->socket.sun_path) == -1)
1195       log_Printf(LogERROR, "%s: Failed to remove: %s\n", s->socket.sun_path,
1196                 strerror(errno));
1197     memset(&s->socket, '\0', sizeof s->socket);
1198     s->fd = -1;
1199   }
1200 }
1201
1202 void
1203 mp_LinkLost(struct mp *mp, struct datalink *dl)
1204 {
1205   if (mp->seq.min_in == dl->mp.seq)
1206     /* We've lost the link that's holding everything up ! */
1207     mp_Assemble(mp, NULL, NULL);
1208 }
1209
1210 size_t
1211 mp_QueueLen(struct mp *mp)
1212 {
1213   return link_QueueLen(&mp->link);
1214 }