source: rtems/cpukit/pppd/cbcp.c @ 0173ab8

4.104.114.84.95
Last change on this file since 0173ab8 was d0950ad, checked in by Joel Sherrill <joel.sherrill@…>, on 11/30/99 at 22:12:50

Added port of ppp-2.3.5 from Tomasz Domin <dot@…> of ComArch? SA.
Tomasz only tested this on the mpc823.

The official site for the original source for this PPP implementation is:

ftp://cs.anu.edu.au/pub/software/ppp

NOTE: As of 11/30/1999, the current version of this source is 2.3.10.

  • Property mode set to 100644
File size: 8.4 KB
Line 
1/*
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$"; */
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 */
40static void cbcp_init      __P((int unit));
41static void cbcp_open      __P((int unit));
42static void cbcp_lowerup   __P((int unit));
43static void cbcp_input     __P((int unit, u_char *pkt, int len));
44static void cbcp_protrej   __P((int unit));
45static int  cbcp_printpkt  __P((u_char *pkt, int len,
46                                void (*printer) __P((void *, char *, ...)),
47                                void *arg));
48
49struct 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
67cbcp_state cbcp[NUM_PPP];       
68
69/* internal prototypes */
70
71static void cbcp_recvreq __P((cbcp_state *us, char *pckt, int len));
72static void cbcp_resp __P((cbcp_state *us));
73static void cbcp_up __P((cbcp_state *us));
74static void cbcp_recvack __P((cbcp_state *us, char *pckt, int len));
75static void cbcp_send __P((cbcp_state *us, u_char code, u_char *buf, int len));
76
77/* init state */
78static void
79cbcp_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 */
91static void
92cbcp_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
105static void
106cbcp_open(unit)
107    int unit;
108{
109    syslog(LOG_DEBUG, "cbcp_open");
110}
111
112/* process an incomming packet */
113static void
114cbcp_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 */
169void cbcp_protrej(int iface)
170{
171}
172
173char *cbcp_codenames[] = {
174    "Request", "Response", "Ack"
175};
176
177char *cbcp_optionnames[] = {
178    "NoCallback",
179    "UserDefined",
180    "AdminDefined",
181    "List"
182};
183
184/* pretty print a packet */
185static int
186cbcp_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 */
263static void
264cbcp_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
315static void
316cbcp_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
367static void
368cbcp_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
393static void
394cbcp_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
422extern int persist;
423
424/* ok peer will do callback */
425static void
426cbcp_up(us)
427    cbcp_state *us;
428{
429    persist = 0;
430    lcp_close(0, "Call me back, please");
431}
Note: See TracBrowser for help on using the repository browser.