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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [c/] [src/] [libnetworking/] [pppd/] [demand.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/*
2
 * demand.c - Support routines for demand-dialling.
3
 *
4
 * Copyright (c) 1993 The Australian National 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 the Australian National University.  The name of the University
13
 * may not be used to endorse or promote products derived from this
14
 * 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
#define RCSID   "demand.c,v 1.3 2002/01/31 21:40:47 joel Exp";
21
 
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <string.h>
25
#include <errno.h>
26
#include <fcntl.h>
27
#include <netdb.h>
28
#include <sys/param.h>
29
#include <sys/types.h>
30
#include <sys/wait.h>
31
#include <sys/time.h>
32
#include <sys/resource.h>
33
#include <sys/stat.h>
34
#include <sys/socket.h>
35
#ifdef PPP_FILTER
36
#include <net/if.h>
37
#include <net/bpf.h>
38
#include <pcap.h>
39
#endif
40
 
41
#include "pppd.h"
42
#include "fsm.h"
43
#include "ipcp.h"
44
#include "lcp.h"
45
 
46
static const char rcsid[] = RCSID;
47
 
48
char *frame;
49
int framelen;
50
int framemax;
51
int escape_flag;
52
int flush_flag;
53
int fcs;
54
 
55
struct packet {
56
    int length;
57
    struct packet *next;
58
    unsigned char data[1];
59
};
60
 
61
struct packet *pend_q;
62
struct packet *pend_qtail;
63
 
64
static int active_packet __P((unsigned char *, int));
65
 
66
/*
67
 * demand_conf - configure the interface for doing dial-on-demand.
68
 */
69
void
70
demand_conf()
71
{
72
    int i;
73
    struct protent *protp;
74
 
75
/*    framemax = lcp_allowoptions[0].mru;
76
    if (framemax < PPP_MRU) */
77
        framemax = PPP_MRU;
78
    framemax += PPP_HDRLEN + PPP_FCSLEN;
79
    frame = malloc(framemax);
80
    if (frame == NULL)
81
        novm("demand frame");
82
    framelen = 0;
83
    pend_q = NULL;
84
    escape_flag = 0;
85
    flush_flag = 0;
86
    fcs = PPP_INITFCS;
87
 
88
    ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);
89
    ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);
90
 
91
#ifdef PPP_FILTER
92
    set_filters(&pass_filter, &active_filter);
93
#endif
94
 
95
    /*
96
     * Call the demand_conf procedure for each protocol that's got one.
97
     */
98
    for (i = 0; (protp = protocols[i]) != NULL; ++i)
99
        if (protp->enabled_flag && protp->demand_conf != NULL)
100
            if (!((*protp->demand_conf)(0)))
101
                die(1);
102
}
103
 
104
 
105
/*
106
 * demand_block - set each network protocol to block further packets.
107
 */
108
void
109
demand_block()
110
{
111
    int i;
112
    struct protent *protp;
113
 
114
    for (i = 0; (protp = protocols[i]) != NULL; ++i)
115
        if (protp->enabled_flag && protp->demand_conf != NULL)
116
            sifnpmode(0, protp->protocol & ~0x8000, NPMODE_QUEUE);
117
    get_loop_output();
118
}
119
 
120
/*
121
 * demand_discard - set each network protocol to discard packets
122
 * with an error.
123
 */
124
void
125
demand_discard()
126
{
127
    struct packet *pkt, *nextpkt;
128
    int i;
129
    struct protent *protp;
130
 
131
    for (i = 0; (protp = protocols[i]) != NULL; ++i)
132
        if (protp->enabled_flag && protp->demand_conf != NULL)
133
            sifnpmode(0, protp->protocol & ~0x8000, NPMODE_ERROR);
134
    get_loop_output();
135
 
136
    /* discard all saved packets */
137
    for (pkt = pend_q; pkt != NULL; pkt = nextpkt) {
138
        nextpkt = pkt->next;
139
        free(pkt);
140
    }
141
    pend_q = NULL;
142
    framelen = 0;
143
    flush_flag = 0;
144
    escape_flag = 0;
145
    fcs = PPP_INITFCS;
146
}
147
 
148
/*
149
 * demand_unblock - set each enabled network protocol to pass packets.
150
 */
151
void
152
demand_unblock()
153
{
154
    int i;
155
    struct protent *protp;
156
 
157
    for (i = 0; (protp = protocols[i]) != NULL; ++i)
158
        if (protp->enabled_flag && protp->demand_conf != NULL)
159
            sifnpmode(0, protp->protocol & ~0x8000, NPMODE_PASS);
160
}
161
 
162
/*
163
 * FCS lookup table as calculated by genfcstab.
164
 */
165
static u_short fcstab[256] = {
166
        0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
167
        0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
168
        0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
169
        0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
170
        0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
171
        0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
172
        0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
173
        0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
174
        0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
175
        0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
176
        0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
177
        0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
178
        0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
179
        0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
180
        0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
181
        0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
182
        0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
183
        0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
184
        0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
185
        0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
186
        0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
187
        0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
188
        0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
189
        0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
190
        0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
191
        0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
192
        0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
193
        0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
194
        0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
195
        0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
196
        0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
197
        0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
198
};
199
 
200
/*
201
 * loop_chars - process characters received from the loopback.
202
 * Calls loop_frame when a complete frame has been accumulated.
203
 * Return value is 1 if we need to bring up the link, 0 otherwise.
204
 */
205
int
206
loop_chars(p, n)
207
    unsigned char *p;
208
    int n;
209
{
210
    int c, rv;
211
 
212
    rv = 0;
213
    for (; n > 0; --n) {
214
        c = *p++;
215
        if (c == PPP_FLAG) {
216
            if (!escape_flag && !flush_flag
217
                && framelen > 2 && fcs == PPP_GOODFCS) {
218
                framelen -= 2;
219
                if (loop_frame(frame, framelen))
220
                    rv = 1;
221
            }
222
            framelen = 0;
223
            flush_flag = 0;
224
            escape_flag = 0;
225
            fcs = PPP_INITFCS;
226
            continue;
227
        }
228
        if (flush_flag)
229
            continue;
230
        if (escape_flag) {
231
            c ^= PPP_TRANS;
232
            escape_flag = 0;
233
        } else if (c == PPP_ESCAPE) {
234
            escape_flag = 1;
235
            continue;
236
        }
237
        if (framelen >= framemax) {
238
            flush_flag = 1;
239
            continue;
240
        }
241
        frame[framelen++] = c;
242
        fcs = PPP_FCS(fcs, c);
243
    }
244
    return rv;
245
}
246
 
247
/*
248
 * loop_frame - given a frame obtained from the loopback,
249
 * decide whether to bring up the link or not, and, if we want
250
 * to transmit this frame later, put it on the pending queue.
251
 * Return value is 1 if we need to bring up the link, 0 otherwise.
252
 * We assume that the kernel driver has already applied the
253
 * pass_filter, so we won't get packets it rejected.
254
 * We apply the active_filter to see if we want this packet to
255
 * bring up the link.
256
 */
257
int
258
loop_frame(frame, len)
259
    unsigned char *frame;
260
    int len;
261
{
262
    struct packet *pkt;
263
 
264
    /* dbglog("from loop: %P", frame, len); */
265
    if (len < PPP_HDRLEN)
266
        return 0;
267
    if ((PPP_PROTOCOL(frame) & 0x8000) != 0)
268
        return 0;                /* shouldn't get any of these anyway */
269
    if (!active_packet(frame, len))
270
        return 0;
271
 
272
    pkt = (struct packet *) malloc(sizeof(struct packet) + len);
273
    if (pkt != NULL) {
274
        pkt->length = len;
275
        pkt->next = NULL;
276
        memcpy(pkt->data, frame, len);
277
        if (pend_q == NULL)
278
            pend_q = pkt;
279
        else
280
            pend_qtail->next = pkt;
281
        pend_qtail = pkt;
282
    }
283
    return 1;
284
}
285
 
286
/*
287
 * demand_rexmit - Resend all those frames which we got via the
288
 * loopback, now that the real serial link is up.
289
 */
290
void
291
demand_rexmit(proto)
292
    int proto;
293
{
294
    struct packet *pkt, *prev, *nextpkt;
295
 
296
    prev = NULL;
297
    pkt = pend_q;
298
    pend_q = NULL;
299
    for (; pkt != NULL; pkt = nextpkt) {
300
        nextpkt = pkt->next;
301
        if (PPP_PROTOCOL(pkt->data) == proto) {
302
            output(0, pkt->data, pkt->length);
303
            free(pkt);
304
        } else {
305
            if (prev == NULL)
306
                pend_q = pkt;
307
            else
308
                prev->next = pkt;
309
            prev = pkt;
310
        }
311
    }
312
    pend_qtail = prev;
313
    if (prev != NULL)
314
        prev->next = NULL;
315
}
316
 
317
/*
318
 * Scan a packet to decide whether it is an "active" packet,
319
 * that is, whether it is worth bringing up the link for.
320
 */
321
static int
322
active_packet(p, len)
323
    unsigned char *p;
324
    int len;
325
{
326
    int proto, i;
327
    struct protent *protp;
328
 
329
    if (len < PPP_HDRLEN)
330
        return 0;
331
    proto = PPP_PROTOCOL(p);
332
#ifdef PPP_FILTER
333
    if (active_filter.bf_len != 0
334
        && bpf_filter(active_filter.bf_insns, frame, len, len) == 0)
335
        return 0;
336
#endif
337
    for (i = 0; (protp = protocols[i]) != NULL; ++i) {
338
        if (protp->protocol < 0xC000 && (protp->protocol & ~0x8000) == proto) {
339
            if (!protp->enabled_flag)
340
                return 0;
341
            if (protp->active_pkt == NULL)
342
                return 1;
343
            return (*protp->active_pkt)(p, len);
344
        }
345
    }
346
    return 0;                    /* not a supported protocol !!?? */
347
}

powered by: WebSVN 2.1.0

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