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

Subversion Repositories openrisc_me

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

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

Line No. Rev Author Line
1 30 unneback
/*
2
 * cbcp - Call Back Configuration Protocol.
3
 *
4
 * Copyright (c) 1995 Pedro Roque Marques
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 Pedro Roque Marques.  The name of the author may not be used to
13
 * endorse or promote products derived from this software without
14
 * specific prior written permission.
15
 *
16
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19
 */
20
 
21
#ifndef lint
22
/* static char rcsid[] = "$Id: cbcp.c,v 1.2 2001-09-27 12:01:57 chris Exp $"; */
23
#endif
24
 
25
#include <stdio.h>
26
#include <string.h>
27
#include <sys/types.h>
28
#include <sys/time.h>
29
#include <syslog.h>
30
 
31
#include "pppd.h"
32
#include "cbcp.h"
33
#include "fsm.h"
34
#include "lcp.h"
35
#include "ipcp.h"
36
 
37
/*
38
 * Protocol entry points.
39
 */
40
static void cbcp_init      __P((int unit));
41
static void cbcp_open      __P((int unit));
42
static void cbcp_lowerup   __P((int unit));
43
static void cbcp_input     __P((int unit, u_char *pkt, int len));
44
static void cbcp_protrej   __P((int unit));
45
static int  cbcp_printpkt  __P((u_char *pkt, int len,
46
                                void (*printer) __P((void *, char *, ...)),
47
                                void *arg));
48
 
49
struct protent cbcp_protent = {
50
    PPP_CBCP,
51
    cbcp_init,
52
    cbcp_input,
53
    cbcp_protrej,
54
    cbcp_lowerup,
55
    NULL,
56
    cbcp_open,
57
    NULL,
58
    cbcp_printpkt,
59
    NULL,
60
    0,
61
    "CBCP",
62
    NULL,
63
    NULL,
64
    NULL
65
};
66
 
67
cbcp_state cbcp[NUM_PPP];
68
 
69
/* internal prototypes */
70
 
71
static void cbcp_recvreq __P((cbcp_state *us, char *pckt, int len));
72
static void cbcp_resp __P((cbcp_state *us));
73
static void cbcp_up __P((cbcp_state *us));
74
static void cbcp_recvack __P((cbcp_state *us, char *pckt, int len));
75
static void cbcp_send __P((cbcp_state *us, u_char code, u_char *buf, int len));
76
 
77
/* init state */
78
static void
79
cbcp_init(iface)
80
    int iface;
81
{
82
    cbcp_state *us;
83
 
84
    us = &cbcp[iface];
85
    memset(us, 0, sizeof(cbcp_state));
86
    us->us_unit = iface;
87
    us->us_type |= (1 << CB_CONF_NO);
88
}
89
 
90
/* lower layer is up */
91
static void
92
cbcp_lowerup(iface)
93
    int iface;
94
{
95
    cbcp_state *us = &cbcp[iface];
96
 
97
 
98
    syslog(LOG_DEBUG, "cbcp_lowerup");
99
    syslog(LOG_DEBUG, "want: %d", us->us_type);
100
 
101
    if (us->us_type == CB_CONF_USER)
102
        syslog(LOG_DEBUG, "phone no: %s", us->us_number);
103
}
104
 
105
static void
106
cbcp_open(unit)
107
    int unit;
108
{
109
    syslog(LOG_DEBUG, "cbcp_open");
110
}
111
 
112
/* process an incomming packet */
113
static void
114
cbcp_input(unit, inpacket, pktlen)
115
    int unit;
116
    u_char *inpacket;
117
    int pktlen;
118
{
119
    u_char *inp;
120
    u_char code, id;
121
    u_short len;
122
 
123
    cbcp_state *us = &cbcp[unit];
124
 
125
    inp = inpacket;
126
 
127
    if (pktlen < CBCP_MINLEN) {
128
        syslog(LOG_ERR, "CBCP packet is too small");
129
        return;
130
    }
131
 
132
    GETCHAR(code, inp);
133
    GETCHAR(id, inp);
134
    GETSHORT(len, inp);
135
 
136
#if 0
137
    if (len > pktlen) {
138
        syslog(LOG_ERR, "CBCP packet: invalid length");
139
        return;
140
    }
141
#endif
142
 
143
    len -= CBCP_MINLEN;
144
 
145
    switch(code) {
146
    case CBCP_REQ:
147
        us->us_id = id;
148
        cbcp_recvreq(us, inp, len);
149
        break;
150
 
151
    case CBCP_RESP:
152
        syslog(LOG_DEBUG, "CBCP_RESP received");
153
        break;
154
 
155
    case CBCP_ACK:
156
        if (id != us->us_id)
157
            syslog(LOG_DEBUG, "id doesn't match: expected %d recv %d",
158
                   us->us_id, id);
159
 
160
        cbcp_recvack(us, inp, len);
161
        break;
162
 
163
    default:
164
        break;
165
    }
166
}
167
 
168
/* protocol was rejected by foe */
169
void cbcp_protrej(int iface)
170
{
171
}
172
 
173
char *cbcp_codenames[] = {
174
    "Request", "Response", "Ack"
175
};
176
 
177
char *cbcp_optionnames[] = {
178
    "NoCallback",
179
    "UserDefined",
180
    "AdminDefined",
181
    "List"
182
};
183
 
184
/* pretty print a packet */
185
static int
186
cbcp_printpkt(p, plen, printer, arg)
187
    u_char *p;
188
    int plen;
189
    void (*printer) __P((void *, char *, ...));
190
    void *arg;
191
{
192
    int code, opt, id, len, olen, delay;
193
    u_char *pstart;
194
 
195
    if (plen < HEADERLEN)
196
        return 0;
197
    pstart = p;
198
    GETCHAR(code, p);
199
    GETCHAR(id, p);
200
    GETSHORT(len, p);
201
    if (len < HEADERLEN || len > plen)
202
        return 0;
203
 
204
    if (code >= 1 && code <= sizeof(cbcp_codenames) / sizeof(char *))
205
        printer(arg, " %s", cbcp_codenames[code-1]);
206
    else
207
        printer(arg, " code=0x%x", code);
208
 
209
    printer(arg, " id=0x%x", id);
210
    len -= HEADERLEN;
211
 
212
    switch (code) {
213
    case CBCP_REQ:
214
    case CBCP_RESP:
215
    case CBCP_ACK:
216
        while(len >= 2) {
217
            GETCHAR(opt, p);
218
            GETCHAR(olen, p);
219
 
220
            if (olen < 2 || olen > len) {
221
                break;
222
            }
223
 
224
            printer(arg, " <");
225
            len -= olen;
226
 
227
            if (opt >= 1 && opt <= sizeof(cbcp_optionnames) / sizeof(char *))
228
                printer(arg, " %s", cbcp_optionnames[opt-1]);
229
            else
230
                printer(arg, " option=0x%x", opt);
231
 
232
            if (olen > 2) {
233
                GETCHAR(delay, p);
234
                printer(arg, " delay = %d", delay);
235
            }
236
 
237
            if (olen > 3) {
238
                int addrt;
239
                char str[256];
240
 
241
                GETCHAR(addrt, p);
242
                memcpy(str, p, olen - 4);
243
                str[olen - 4] = 0;
244
                printer(arg, " number = %s", str);
245
            }
246
            printer(arg, ">");
247
            break;
248
        }
249
 
250
    default:
251
        break;
252
    }
253
 
254
    for (; len > 0; --len) {
255
        GETCHAR(code, p);
256
        printer(arg, " %.2x", code);
257
    }
258
 
259
    return p - pstart;
260
}
261
 
262
/* received CBCP request */
263
static void
264
cbcp_recvreq(us, pckt, pcktlen)
265
    cbcp_state *us;
266
    char *pckt;
267
    int pcktlen;
268
{
269
    u_char type, opt_len, delay, addr_type;
270
    char address[256];
271
    int len = pcktlen;
272
 
273
    address[0] = 0;
274
 
275
    while (len) {
276
        syslog(LOG_DEBUG, "length: %d", len);
277
 
278
        GETCHAR(type, pckt);
279
        GETCHAR(opt_len, pckt);
280
 
281
        if (opt_len > 2)
282
            GETCHAR(delay, pckt);
283
 
284
        us->us_allowed |= (1 << type);
285
 
286
        switch(type) {
287
        case CB_CONF_NO:
288
            syslog(LOG_DEBUG, "no callback allowed");
289
            break;
290
 
291
        case CB_CONF_USER:
292
            syslog(LOG_DEBUG, "user callback allowed");
293
            if (opt_len > 4) {
294
                GETCHAR(addr_type, pckt);
295
                memcpy(address, pckt, opt_len - 4);
296
                address[opt_len - 4] = 0;
297
                if (address[0])
298
                    syslog(LOG_DEBUG, "address: %s", address);
299
            }
300
            break;
301
 
302
        case CB_CONF_ADMIN:
303
            syslog(LOG_DEBUG, "user admin defined allowed");
304
            break;
305
 
306
        case CB_CONF_LIST:
307
            break;
308
        }
309
        len -= opt_len;
310
    }
311
 
312
    cbcp_resp(us);
313
}
314
 
315
static void
316
cbcp_resp(us)
317
    cbcp_state *us;
318
{
319
    u_char cb_type;
320
    u_char buf[256];
321
    u_char *bufp = buf;
322
    int len = 0;
323
 
324
    cb_type = us->us_allowed & us->us_type;
325
    syslog(LOG_DEBUG, "cbcp_resp cb_type=%d", cb_type);
326
 
327
#if 0
328
    if (!cb_type)
329
        lcp_down(us->us_unit);
330
#endif
331
 
332
    if (cb_type & ( 1 << CB_CONF_USER ) ) {
333
        syslog(LOG_DEBUG, "cbcp_resp CONF_USER");
334
        PUTCHAR(CB_CONF_USER, bufp);
335
        len = 3 + 1 + strlen(us->us_number) + 1;
336
        PUTCHAR(len , bufp);
337
        PUTCHAR(5, bufp); /* delay */
338
        PUTCHAR(1, bufp);
339
        BCOPY(us->us_number, bufp, strlen(us->us_number) + 1);
340
        cbcp_send(us, CBCP_RESP, buf, len);
341
        return;
342
    }
343
 
344
    if (cb_type & ( 1 << CB_CONF_ADMIN ) ) {
345
        syslog(LOG_DEBUG, "cbcp_resp CONF_ADMIN");
346
        PUTCHAR(CB_CONF_ADMIN, bufp);
347
        len = 3 + 1;
348
        PUTCHAR(len , bufp);
349
        PUTCHAR(5, bufp); /* delay */
350
        PUTCHAR(0, bufp);
351
        cbcp_send(us, CBCP_RESP, buf, len);
352
        return;
353
    }
354
 
355
    if (cb_type & ( 1 << CB_CONF_NO ) ) {
356
        syslog(LOG_DEBUG, "cbcp_resp CONF_NO");
357
        PUTCHAR(CB_CONF_NO, bufp);
358
        len = 3;
359
        PUTCHAR(len , bufp);
360
        PUTCHAR(0, bufp);
361
        cbcp_send(us, CBCP_RESP, buf, len);
362
        (*ipcp_protent.open)(us->us_unit);
363
        return;
364
    }
365
}
366
 
367
static void
368
cbcp_send(us, code, buf, len)
369
    cbcp_state *us;
370
    u_char code;
371
    u_char *buf;
372
    int len;
373
{
374
    u_char *outp;
375
    int outlen;
376
 
377
    outp = outpacket_buf;
378
 
379
    outlen = 4 + len;
380
 
381
    MAKEHEADER(outp, PPP_CBCP);
382
 
383
    PUTCHAR(code, outp);
384
    PUTCHAR(us->us_id, outp);
385
    PUTSHORT(outlen, outp);
386
 
387
    if (len)
388
        BCOPY(buf, outp, len);
389
 
390
    output(us->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
391
}
392
 
393
static void
394
cbcp_recvack(us, pckt, len)
395
    cbcp_state *us;
396
    char *pckt;
397
    int len;
398
{
399
    u_char type, delay, addr_type;
400
    int opt_len;
401
    char address[256];
402
 
403
    if (len) {
404
        GETCHAR(type, pckt);
405
        GETCHAR(opt_len, pckt);
406
 
407
        if (opt_len > 2)
408
            GETCHAR(delay, pckt);
409
 
410
        if (opt_len > 4) {
411
            GETCHAR(addr_type, pckt);
412
            memcpy(address, pckt, opt_len - 4);
413
            address[opt_len - 4] = 0;
414
            if (address[0])
415
               syslog(LOG_DEBUG, "peer will call: %s", address);
416
        }
417
    }
418
 
419
    cbcp_up(us);
420
}
421
 
422
extern int persist;
423
 
424
/* ok peer will do callback */
425
static void
426
cbcp_up(us)
427
    cbcp_state *us;
428
{
429
    persist = 0;
430
    lcp_close(0, "Call me back, please");
431
}

powered by: WebSVN 2.1.0

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