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

Subversion Repositories openrisc_me

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

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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