OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [libnetworking/] [pppd/] [fsm.c] - Blame information for rev 173

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
2
 * fsm.c - {Link, IP} Control Protocol Finite State Machine.
3
 *
4
 * Copyright (c) 1989 Carnegie Mellon University.
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms are permitted
8
 * provided that the above copyright notice and this paragraph are
9
 * duplicated in all such forms and that any documentation,
10
 * advertising materials, and other materials related to such
11
 * distribution and use acknowledge that the software was developed
12
 * by Carnegie Mellon University.  The name of the
13
 * University may not be used to endorse or promote products derived
14
 * from this software without specific prior written permission.
15
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18
 */
19
 
20
#ifndef lint
21
/* static char rcsid[] = "$Id: fsm.c,v 1.2 2001-09-27 12:01:57 chris Exp $"; */
22
#endif
23
#define log_packet(p, len, prefix, level)
24
/*
25
 * TODO:
26
 * Randomize fsm id on link/init.
27
 * Deal with variable outgoing MTU.
28
 */
29
 
30
#include <stdio.h>
31
#include <string.h>
32
#include <sys/types.h>
33
#include <syslog.h>
34
 
35
#include "pppd.h"
36
#include "fsm.h"
37
 
38
static void fsm_timeout __P((void *));
39
static void fsm_rconfreq __P((fsm *, int, u_char *, int));
40
static void fsm_rconfack __P((fsm *, int, u_char *, int));
41
static void fsm_rconfnakrej __P((fsm *, int, int, u_char *, int));
42
static void fsm_rtermreq __P((fsm *, int, u_char *, int));
43
static void fsm_rtermack __P((fsm *));
44
static void fsm_rcoderej __P((fsm *, u_char *, int));
45
static void fsm_sconfreq __P((fsm *, int));
46
 
47
#define PROTO_NAME(f)   ((f)->callbacks->proto_name)
48
 
49
int peer_mru[NUM_PPP];
50
 
51
 
52
/*
53
 * fsm_init - Initialize fsm.
54
 *
55
 * Initialize fsm state.
56
 */
57
void
58
fsm_init(f)
59
    fsm *f;
60
{
61
    f->state = INITIAL;
62
    f->flags = 0;
63
    f->id = 0;                           /* XXX Start with random id? */
64
    f->timeouttime = DEFTIMEOUT;
65
    f->maxconfreqtransmits = DEFMAXCONFREQS;
66
    f->maxtermtransmits = DEFMAXTERMREQS;
67
    f->maxnakloops = DEFMAXNAKLOOPS;
68
    f->term_reason_len = 0;
69
}
70
 
71
 
72
/*
73
 * fsm_lowerup - The lower layer is up.
74
 */
75
void
76
fsm_lowerup(f)
77
    fsm *f;
78
{
79
    switch( f->state ){
80
    case INITIAL:
81
        f->state = CLOSED;
82
        break;
83
 
84
    case STARTING:
85
        if( f->flags & OPT_SILENT )
86
            f->state = STOPPED;
87
        else {
88
            /* Send an initial configure-request */
89
            fsm_sconfreq(f, 0);
90
            f->state = REQSENT;
91
        }
92
        break;
93
 
94
    default:
95
        FSMDEBUG((LOG_INFO, "%s: Up event in state %d!",
96
                  PROTO_NAME(f), f->state));
97
    }
98
}
99
 
100
 
101
/*
102
 * fsm_lowerdown - The lower layer is down.
103
 *
104
 * Cancel all timeouts and inform upper layers.
105
 */
106
void
107
fsm_lowerdown(f)
108
    fsm *f;
109
{
110
    switch( f->state ){
111
    case CLOSED:
112
        f->state = INITIAL;
113
        break;
114
 
115
    case STOPPED:
116
        f->state = STARTING;
117
        if( f->callbacks->starting )
118
            (*f->callbacks->starting)(f);
119
        break;
120
 
121
    case CLOSING:
122
        f->state = INITIAL;
123
        UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
124
        break;
125
 
126
    case STOPPING:
127
    case REQSENT:
128
    case ACKRCVD:
129
    case ACKSENT:
130
        f->state = STARTING;
131
        UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
132
        break;
133
 
134
    case OPENED:
135
        if( f->callbacks->down )
136
            (*f->callbacks->down)(f);
137
        f->state = STARTING;
138
        break;
139
 
140
    default:
141
        FSMDEBUG((LOG_INFO, "%s: Down event in state %d!",
142
                  PROTO_NAME(f), f->state));
143
    }
144
}
145
 
146
 
147
/*
148
 * fsm_open - Link is allowed to come up.
149
 */
150
void
151
fsm_open(f)
152
    fsm *f;
153
{
154
    switch( f->state ){
155
    case INITIAL:
156
        f->state = STARTING;
157
        if( f->callbacks->starting )
158
            (*f->callbacks->starting)(f);
159
        break;
160
 
161
    case CLOSED:
162
        if( f->flags & OPT_SILENT )
163
            f->state = STOPPED;
164
        else {
165
            /* Send an initial configure-request */
166
            fsm_sconfreq(f, 0);
167
            f->state = REQSENT;
168
        }
169
        break;
170
 
171
    case CLOSING:
172
        f->state = STOPPING;
173
        /* fall through */
174
    case STOPPED:
175
    case OPENED:
176
        if( f->flags & OPT_RESTART ){
177
            fsm_lowerdown(f);
178
            fsm_lowerup(f);
179
        }
180
        break;
181
    }
182
}
183
 
184
 
185
/*
186
 * fsm_close - Start closing connection.
187
 *
188
 * Cancel timeouts and either initiate close or possibly go directly to
189
 * the CLOSED state.
190
 */
191
void
192
fsm_close(f, reason)
193
    fsm *f;
194
    char *reason;
195
{
196
    f->term_reason = reason;
197
    f->term_reason_len = (reason == NULL? 0: strlen(reason));
198
    switch( f->state ){
199
    case STARTING:
200
        f->state = INITIAL;
201
        break;
202
    case STOPPED:
203
        f->state = CLOSED;
204
        break;
205
    case STOPPING:
206
        f->state = CLOSING;
207
        break;
208
 
209
    case REQSENT:
210
    case ACKRCVD:
211
    case ACKSENT:
212
    case OPENED:
213
        if( f->state != OPENED )
214
            UNTIMEOUT(fsm_timeout, f);  /* Cancel timeout */
215
        else if( f->callbacks->down )
216
            (*f->callbacks->down)(f);   /* Inform upper layers we're down */
217
 
218
        /* Init restart counter, send Terminate-Request */
219
        f->retransmits = f->maxtermtransmits;
220
        fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
221
                  (u_char *) f->term_reason, f->term_reason_len);
222
        TIMEOUT(fsm_timeout, f, f->timeouttime);
223
        --f->retransmits;
224
 
225
        f->state = CLOSING;
226
        break;
227
    }
228
}
229
 
230
 
231
/*
232
 * fsm_timeout - Timeout expired.
233
 */
234
static void
235
fsm_timeout(arg)
236
    void *arg;
237
{
238
    fsm *f = (fsm *) arg;
239
 
240
    switch (f->state) {
241
    case CLOSING:
242
    case STOPPING:
243
        if( f->retransmits <= 0 ){
244
            /*
245
             * We've waited for an ack long enough.  Peer probably heard us.
246
             */
247
            f->state = (f->state == CLOSING)? CLOSED: STOPPED;
248
            if( f->callbacks->finished )
249
                (*f->callbacks->finished)(f);
250
        } else {
251
            /* Send Terminate-Request */
252
            fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
253
                      (u_char *) f->term_reason, f->term_reason_len);
254
            TIMEOUT(fsm_timeout, f, f->timeouttime);
255
            --f->retransmits;
256
        }
257
        break;
258
 
259
    case REQSENT:
260
    case ACKRCVD:
261
    case ACKSENT:
262
        if (f->retransmits <= 0) {
263
            syslog(LOG_WARNING, "%s: timeout sending Config-Requests",
264
                   PROTO_NAME(f));
265
            f->state = STOPPED;
266
            if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished )
267
                (*f->callbacks->finished)(f);
268
 
269
        } else {
270
            /* Retransmit the configure-request */
271
            if (f->callbacks->retransmit)
272
                (*f->callbacks->retransmit)(f);
273
            fsm_sconfreq(f, 1);         /* Re-send Configure-Request */
274
            if( f->state == ACKRCVD )
275
                f->state = REQSENT;
276
        }
277
        break;
278
 
279
    default:
280
        FSMDEBUG((LOG_INFO, "%s: Timeout event in state %d!",
281
                  PROTO_NAME(f), f->state));
282
    }
283
}
284
 
285
 
286
/*
287
 * fsm_input - Input packet.
288
 */
289
void
290
fsm_input(f, inpacket, l)
291
    fsm *f;
292
    u_char *inpacket;
293
    int l;
294
{
295
    u_char *inp;
296
    u_char code, id;
297
    int len;
298
 
299
    /*
300
     * Parse header (code, id and length).
301
     * If packet too short, drop it.
302
     */
303
    inp = inpacket;
304
    if (l < HEADERLEN) {
305
        FSMDEBUG((LOG_WARNING, "fsm_input(%x): Rcvd short header.",
306
                  f->protocol));
307
        return;
308
    }
309
    GETCHAR(code, inp);
310
    GETCHAR(id, inp);
311
    GETSHORT(len, inp);
312
    if (len < HEADERLEN) {
313
        FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd illegal length.",
314
                  f->protocol));
315
        return;
316
    }
317
    if (len > l) {
318
        FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd short packet.",
319
                  f->protocol));
320
        return;
321
    }
322
    len -= HEADERLEN;           /* subtract header length */
323
 
324
    if( f->state == INITIAL || f->state == STARTING ){
325
        FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd packet in state %d.",
326
                  f->protocol, f->state));
327
        return;
328
    }
329
 
330
    /*
331
     * Action depends on code.
332
     */
333
    switch (code) {
334
    case CONFREQ:
335
        fsm_rconfreq(f, id, inp, len);
336
        break;
337
 
338
    case CONFACK:
339
        fsm_rconfack(f, id, inp, len);
340
        break;
341
 
342
    case CONFNAK:
343
    case CONFREJ:
344
        fsm_rconfnakrej(f, code, id, inp, len);
345
        break;
346
 
347
    case TERMREQ:
348
        fsm_rtermreq(f, id, inp, len);
349
        break;
350
 
351
    case TERMACK:
352
        fsm_rtermack(f);
353
        break;
354
 
355
    case CODEREJ:
356
        fsm_rcoderej(f, inp, len);
357
        break;
358
 
359
    default:
360
        if( !f->callbacks->extcode
361
           || !(*f->callbacks->extcode)(f, code, id, inp, len) )
362
            fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN);
363
        break;
364
    }
365
}
366
 
367
 
368
/*
369
 * fsm_rconfreq - Receive Configure-Request.
370
 */
371
static void
372
fsm_rconfreq(f, id, inp, len)
373
    fsm *f;
374
    u_char id;
375
    u_char *inp;
376
    int len;
377
{
378
    int code, reject_if_disagree;
379
 
380
    FSMDEBUG((LOG_INFO, "fsm_rconfreq(%s): Rcvd id %d.", PROTO_NAME(f), id));
381
    switch( f->state ){
382
    case CLOSED:
383
        /* Go away, we're closed */
384
        fsm_sdata(f, TERMACK, id, NULL, 0);
385
        return;
386
    case CLOSING:
387
    case STOPPING:
388
        return;
389
 
390
    case OPENED:
391
        /* Go down and restart negotiation */
392
        if( f->callbacks->down )
393
            (*f->callbacks->down)(f);   /* Inform upper layers */
394
        fsm_sconfreq(f, 0);              /* Send initial Configure-Request */
395
        break;
396
 
397
    case STOPPED:
398
        /* Negotiation started by our peer */
399
        fsm_sconfreq(f, 0);              /* Send initial Configure-Request */
400
        f->state = REQSENT;
401
        break;
402
    }
403
 
404
    /*
405
     * Pass the requested configuration options
406
     * to protocol-specific code for checking.
407
     */
408
    if (f->callbacks->reqci){           /* Check CI */
409
        reject_if_disagree = (f->nakloops >= f->maxnakloops);
410
        code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree);
411
    } else if (len)
412
        code = CONFREJ;                 /* Reject all CI */
413
    else
414
        code = CONFACK;
415
 
416
    /* send the Ack, Nak or Rej to the peer */
417
    fsm_sdata(f, code, id, inp, len);
418
 
419
    if (code == CONFACK) {
420
        if (f->state == ACKRCVD) {
421
            UNTIMEOUT(fsm_timeout, f);  /* Cancel timeout */
422
            f->state = OPENED;
423
            if (f->callbacks->up)
424
                (*f->callbacks->up)(f); /* Inform upper layers */
425
        } else
426
            f->state = ACKSENT;
427
        f->nakloops = 0;
428
 
429
    } else {
430
        /* we sent CONFACK or CONFREJ */
431
        if (f->state != ACKRCVD)
432
            f->state = REQSENT;
433
        if( code == CONFNAK )
434
            ++f->nakloops;
435
    }
436
}
437
 
438
 
439
/*
440
 * fsm_rconfack - Receive Configure-Ack.
441
 */
442
static void
443
fsm_rconfack(f, id, inp, len)
444
    fsm *f;
445
    int id;
446
    u_char *inp;
447
    int len;
448
{
449
    FSMDEBUG((LOG_INFO, "fsm_rconfack(%s): Rcvd id %d.",
450
              PROTO_NAME(f), id));
451
 
452
    if (id != f->reqid || f->seen_ack)          /* Expected id? */
453
        return;                                 /* Nope, toss... */
454
    if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len):
455
          (len == 0)) ){
456
        /* Ack is bad - ignore it */
457
        log_packet(inp, len, "Received bad configure-ack: ", LOG_ERR);
458
        FSMDEBUG((LOG_INFO, "%s: received bad Ack (length %d)",
459
                  PROTO_NAME(f), len));
460
        return;
461
    }
462
    f->seen_ack = 1;
463
 
464
    switch (f->state) {
465
    case CLOSED:
466
    case STOPPED:
467
        fsm_sdata(f, TERMACK, id, NULL, 0);
468
        break;
469
 
470
    case REQSENT:
471
        f->state = ACKRCVD;
472
        f->retransmits = f->maxconfreqtransmits;
473
        break;
474
 
475
    case ACKRCVD:
476
        /* Huh? an extra valid Ack? oh well... */
477
        UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
478
        fsm_sconfreq(f, 0);
479
        f->state = REQSENT;
480
        break;
481
 
482
    case ACKSENT:
483
        UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
484
        f->state = OPENED;
485
        f->retransmits = f->maxconfreqtransmits;
486
        if (f->callbacks->up)
487
            (*f->callbacks->up)(f);     /* Inform upper layers */
488
        break;
489
 
490
    case OPENED:
491
        /* Go down and restart negotiation */
492
        if (f->callbacks->down)
493
            (*f->callbacks->down)(f);   /* Inform upper layers */
494
        fsm_sconfreq(f, 0);              /* Send initial Configure-Request */
495
        f->state = REQSENT;
496
        break;
497
    }
498
}
499
 
500
 
501
/*
502
 * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
503
 */
504
static void
505
fsm_rconfnakrej(f, code, id, inp, len)
506
    fsm *f;
507
    int code, id;
508
    u_char *inp;
509
    int len;
510
{
511
    int (*proc) __P((fsm *, u_char *, int));
512
    int ret;
513
 
514
    FSMDEBUG((LOG_INFO, "fsm_rconfnakrej(%s): Rcvd id %d.",
515
              PROTO_NAME(f), id));
516
 
517
    if (id != f->reqid || f->seen_ack)  /* Expected id? */
518
        return;                         /* Nope, toss... */
519
    proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci;
520
    if (!proc || !(ret = proc(f, inp, len))) {
521
        /* Nak/reject is bad - ignore it */
522
        log_packet(inp, len, "Received bad configure-nak/rej: ", LOG_ERR);
523
        FSMDEBUG((LOG_INFO, "%s: received bad %s (length %d)",
524
                  PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len));
525
        return;
526
    }
527
    f->seen_ack = 1;
528
 
529
    switch (f->state) {
530
    case CLOSED:
531
    case STOPPED:
532
        fsm_sdata(f, TERMACK, id, NULL, 0);
533
        break;
534
 
535
    case REQSENT:
536
    case ACKSENT:
537
        /* They didn't agree to what we wanted - try another request */
538
        UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
539
        if (ret < 0)
540
            f->state = STOPPED;         /* kludge for stopping CCP */
541
        else
542
            fsm_sconfreq(f, 0);          /* Send Configure-Request */
543
        break;
544
 
545
    case ACKRCVD:
546
        /* Got a Nak/reject when we had already had an Ack?? oh well... */
547
        UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
548
        fsm_sconfreq(f, 0);
549
        f->state = REQSENT;
550
        break;
551
 
552
    case OPENED:
553
        /* Go down and restart negotiation */
554
        if (f->callbacks->down)
555
            (*f->callbacks->down)(f);   /* Inform upper layers */
556
        fsm_sconfreq(f, 0);              /* Send initial Configure-Request */
557
        f->state = REQSENT;
558
        break;
559
    }
560
}
561
 
562
 
563
/*
564
 * fsm_rtermreq - Receive Terminate-Req.
565
 */
566
static void
567
fsm_rtermreq(f, id, p, len)
568
    fsm *f;
569
    int id;
570
    u_char *p;
571
    int len;
572
{
573
    char str[80];
574
 
575
    FSMDEBUG((LOG_INFO, "fsm_rtermreq(%s): Rcvd id %d.",
576
              PROTO_NAME(f), id));
577
 
578
    switch (f->state) {
579
    case ACKRCVD:
580
    case ACKSENT:
581
        f->state = REQSENT;             /* Start over but keep trying */
582
        break;
583
 
584
    case OPENED:
585
        if (len > 0) {
586
            fmtmsg(str, sizeof(str), "%0.*v", len, p);
587
            syslog(LOG_INFO, "%s terminated by peer (%s)", PROTO_NAME(f), str);
588
        } else
589
            syslog(LOG_INFO, "%s terminated by peer", PROTO_NAME(f));
590
        if (f->callbacks->down)
591
            (*f->callbacks->down)(f);   /* Inform upper layers */
592
        f->retransmits = 0;
593
        f->state = STOPPING;
594
        TIMEOUT(fsm_timeout, f, f->timeouttime);
595
        break;
596
    }
597
 
598
    fsm_sdata(f, TERMACK, id, NULL, 0);
599
}
600
 
601
 
602
/*
603
 * fsm_rtermack - Receive Terminate-Ack.
604
 */
605
static void
606
fsm_rtermack(f)
607
    fsm *f;
608
{
609
    FSMDEBUG((LOG_INFO, "fsm_rtermack(%s).", PROTO_NAME(f)));
610
 
611
    switch (f->state) {
612
    case CLOSING:
613
        UNTIMEOUT(fsm_timeout, f);
614
        f->state = CLOSED;
615
        if( f->callbacks->finished )
616
            (*f->callbacks->finished)(f);
617
        break;
618
    case STOPPING:
619
        UNTIMEOUT(fsm_timeout, f);
620
        f->state = STOPPED;
621
        if( f->callbacks->finished )
622
            (*f->callbacks->finished)(f);
623
        break;
624
 
625
    case ACKRCVD:
626
        f->state = REQSENT;
627
        break;
628
 
629
    case OPENED:
630
        if (f->callbacks->down)
631
            (*f->callbacks->down)(f);   /* Inform upper layers */
632
        fsm_sconfreq(f, 0);
633
        break;
634
    }
635
}
636
 
637
 
638
/*
639
 * fsm_rcoderej - Receive an Code-Reject.
640
 */
641
static void
642
fsm_rcoderej(f, inp, len)
643
    fsm *f;
644
    u_char *inp;
645
    int len;
646
{
647
    u_char code, id;
648
 
649
    FSMDEBUG((LOG_INFO, "fsm_rcoderej(%s).", PROTO_NAME(f)));
650
 
651
    if (len < HEADERLEN) {
652
        FSMDEBUG((LOG_INFO, "fsm_rcoderej: Rcvd short Code-Reject packet!"));
653
        return;
654
    }
655
    GETCHAR(code, inp);
656
    GETCHAR(id, inp);
657
    syslog(LOG_WARNING, "%s: Rcvd Code-Reject for code %d, id %d",
658
           PROTO_NAME(f), code, id);
659
 
660
    if( f->state == ACKRCVD )
661
        f->state = REQSENT;
662
}
663
 
664
 
665
/*
666
 * fsm_protreject - Peer doesn't speak this protocol.
667
 *
668
 * Treat this as a catastrophic error (RXJ-).
669
 */
670
void
671
fsm_protreject(f)
672
    fsm *f;
673
{
674
    switch( f->state ){
675
    case CLOSING:
676
        UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
677
        /* fall through */
678
    case CLOSED:
679
        f->state = CLOSED;
680
        if( f->callbacks->finished )
681
            (*f->callbacks->finished)(f);
682
        break;
683
 
684
    case STOPPING:
685
    case REQSENT:
686
    case ACKRCVD:
687
    case ACKSENT:
688
        UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
689
        /* fall through */
690
    case STOPPED:
691
        f->state = STOPPED;
692
        if( f->callbacks->finished )
693
            (*f->callbacks->finished)(f);
694
        break;
695
 
696
    case OPENED:
697
        if( f->callbacks->down )
698
            (*f->callbacks->down)(f);
699
 
700
        /* Init restart counter, send Terminate-Request */
701
        f->retransmits = f->maxtermtransmits;
702
        fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
703
                  (u_char *) f->term_reason, f->term_reason_len);
704
        TIMEOUT(fsm_timeout, f, f->timeouttime);
705
        --f->retransmits;
706
 
707
        f->state = STOPPING;
708
        break;
709
 
710
    default:
711
        FSMDEBUG((LOG_INFO, "%s: Protocol-reject event in state %d!",
712
                  PROTO_NAME(f), f->state));
713
    }
714
}
715
 
716
 
717
/*
718
 * fsm_sconfreq - Send a Configure-Request.
719
 */
720
static void
721
fsm_sconfreq(f, retransmit)
722
    fsm *f;
723
    int retransmit;
724
{
725
    u_char *outp;
726
    int cilen;
727
 
728
    if( f->state != REQSENT && f->state != ACKRCVD && f->state != ACKSENT ){
729
        /* Not currently negotiating - reset options */
730
        if( f->callbacks->resetci )
731
            (*f->callbacks->resetci)(f);
732
        f->nakloops = 0;
733
    }
734
 
735
    if( !retransmit ){
736
        /* New request - reset retransmission counter, use new ID */
737
        f->retransmits = f->maxconfreqtransmits;
738
        f->reqid = ++f->id;
739
    }
740
 
741
    f->seen_ack = 0;
742
 
743
    /*
744
     * Make up the request packet
745
     */
746
    outp = outpacket_buf + PPP_HDRLEN + HEADERLEN;
747
    if( f->callbacks->cilen && f->callbacks->addci ){
748
        cilen = (*f->callbacks->cilen)(f);
749
        if( cilen > peer_mru[f->unit] - HEADERLEN )
750
            cilen = peer_mru[f->unit] - HEADERLEN;
751
        if (f->callbacks->addci)
752
            (*f->callbacks->addci)(f, outp, &cilen);
753
    } else
754
        cilen = 0;
755
 
756
    /* send the request to our peer */
757
    fsm_sdata(f, CONFREQ, f->reqid, outp, cilen);
758
 
759
    /* start the retransmit timer */
760
    --f->retransmits;
761
    TIMEOUT(fsm_timeout, f, f->timeouttime);
762
 
763
    FSMDEBUG((LOG_INFO, "%s: sending Configure-Request, id %d",
764
              PROTO_NAME(f), f->reqid));
765
}
766
 
767
 
768
/*
769
 * fsm_sdata - Send some data.
770
 *
771
 * Used for all packets sent to our peer by this module.
772
 */
773
void
774
fsm_sdata(f, code, id, data, datalen)
775
    fsm *f;
776
    u_char code, id;
777
    u_char *data;
778
    int datalen;
779
{
780
    u_char *outp;
781
    int outlen;
782
 
783
    /* Adjust length to be smaller than MTU */
784
    outp = outpacket_buf;
785
    if (datalen > peer_mru[f->unit] - HEADERLEN)
786
        datalen = peer_mru[f->unit] - HEADERLEN;
787
    if (datalen && data != outp + PPP_HDRLEN + HEADERLEN)
788
        BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen);
789
    outlen = datalen + HEADERLEN;
790
    MAKEHEADER(outp, f->protocol);
791
    PUTCHAR(code, outp);
792
    PUTCHAR(id, outp);
793
    PUTSHORT(outlen, outp);
794
    output(f->unit, outpacket_buf, outlen + PPP_HDRLEN);
795
 
796
    FSMDEBUG((LOG_INFO, "fsm_sdata(%s): Sent code %d, id %d.",
797
              PROTO_NAME(f), code, id));
798
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.