Changeset aee474b in rtems for cpukit/pppd/cbcp.c


Ignore:
Timestamp:
Oct 12, 2001, 1:43:05 PM (18 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
cedf9296
Parents:
ba71076
Message:

2001-10-12 Mike Siers <mikes@…>

  • Update to stable working state. Congratulations Mike! :)
  • modem_example: Directory removed.
  • modem_example/16550.h, modem_example/README, modem_example/modem.c, modem_example/modem.h, modem_example/ppp.c, modem_example/ppp.h, modem_example/pppcompress.c: Files removed.
  • pppd/example/pppd.options: New file.
  • pppd/README, pppd/STATUS, pppd/cbcp.c, pppd/cbcp.h, pppd/chat.c, pppd/pppd.h, pppd/rtemsmain.c: Updated.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/pppd/cbcp.c

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