Annotation of embedaddon/libpdel/ppp/ppp_ccp.c, revision 1.1.1.1

1.1       misho       1: 
                      2: /*
                      3:  * Copyright (c) 2001-2002 Packet Design, LLC.
                      4:  * All rights reserved.
                      5:  * 
                      6:  * Subject to the following obligations and disclaimer of warranty,
                      7:  * use and redistribution of this software, in source or object code
                      8:  * forms, with or without modifications are expressly permitted by
                      9:  * Packet Design; provided, however, that:
                     10:  * 
                     11:  *    (i)  Any and all reproductions of the source or object code
                     12:  *         must include the copyright notice above and the following
                     13:  *         disclaimer of warranties; and
                     14:  *    (ii) No rights are granted, in any manner or form, to use
                     15:  *         Packet Design trademarks, including the mark "PACKET DESIGN"
                     16:  *         on advertising, endorsements, or otherwise except as such
                     17:  *         appears in the above copyright notice or in the software.
                     18:  * 
                     19:  * THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
                     20:  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
                     21:  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
                     22:  * THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
                     23:  * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
                     24:  * OR NON-INFRINGEMENT.  PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
                     25:  * OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
                     26:  * OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
                     27:  * RELIABILITY OR OTHERWISE.  IN NO EVENT SHALL PACKET DESIGN BE
                     28:  * LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
                     29:  * OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
                     30:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
                     31:  * DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
                     32:  * USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
                     33:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     34:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
                     35:  * THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
                     36:  * THE POSSIBILITY OF SUCH DAMAGE.
                     37:  *
                     38:  * Author: Archie Cobbs <archie@freebsd.org>
                     39:  */
                     40: 
                     41: #include "ppp/ppp_defs.h"
                     42: #include "ppp/ppp_log.h"
                     43: #include "ppp/ppp_fsm_option.h"
                     44: #include "ppp/ppp_fsm.h"
                     45: #include "ppp/ppp_auth.h"
                     46: #include "ppp/ppp_node.h"
                     47: #include "ppp/ppp_ccp.h"
                     48: 
                     49: #include <netgraph/ng_mppc.h>
                     50: 
                     51: #ifndef MPPE_56
                     52: #define        MPPE_56         0x00000080
                     53: #undef MPPE_BITS
                     54: #define        MPPE_BITS       0x000000e0
                     55: #endif
                     56: 
                     57: /*
                     58:  * CCP FSM
                     59:  *
                     60:  * XXX This is hard coded to only support MPPC/MPPE compression.
                     61:  * XXX It should be generalized to support multiple PPP compression types.
                     62:  */
                     63: 
                     64: #define MPPC_SUPPORTED         (MPPC_BIT | MPPE_BITS | MPPE_STATELESS)
                     65: 
                     66: /* Memory type */
                     67: #define CCP_MTYPE              "ccp"
                     68: 
                     69: /* CCP compression types */
                     70: enum ccp_type {
                     71:        CCP_OPT_OUI             =0,     /* oui */
                     72:        CCP_OPT_PRED1           =1,     /* predictor type 1 */
                     73:        CCP_OPT_PRED2           =2,     /* predictor type 2 */
                     74:        CCP_OPT_PUDDLE          =3,     /* puddle jumper */
                     75:        CCP_OPT_HWPPC           =16,    /* hewlett-packard ppc */
                     76:        CCP_OPT_STAC            =17,    /* stac electronics lzs */
                     77:        CCP_OPT_MPPC            =18,    /* microsoft mppc/mppe */
                     78:        CCP_OPT_GAND            =19,    /* gandalf fza */
                     79:        CCP_OPT_V42BIS          =20,    /* v.42bis compression */
                     80:        CCP_OPT_BSD             =21,    /* bsd lzw compress */
                     81:        CCP_OPT_DEFLATE         =24,    /* gzip "deflate" compression */
                     82: };
                     83: 
                     84: /* Supported and required FSM codes */
                     85: #define CCP_SUPPORTED_CODES            \
                     86:          (1 << FSM_CODE_CONFIGREQ)     \
                     87:        | (1 << FSM_CODE_CONFIGACK)     \
                     88:        | (1 << FSM_CODE_CONFIGNAK)     \
                     89:        | (1 << FSM_CODE_CONFIGREJ)     \
                     90:        | (1 << FSM_CODE_TERMREQ)       \
                     91:        | (1 << FSM_CODE_TERMACK)       \
                     92:        | (1 << FSM_CODE_CODEREJ)       \
                     93:        | (1 << FSM_CODE_RESETREQ)      \
                     94:        | (1 << FSM_CODE_RESETACK)
                     95: #define CCP_REQUIRED_CODES             \
                     96:          (1 << FSM_CODE_CONFIGREQ)     \
                     97:        | (1 << FSM_CODE_CONFIGACK)     \
                     98:        | (1 << FSM_CODE_CONFIGNAK)     \
                     99:        | (1 << FSM_CODE_CONFIGREJ)     \
                    100:        | (1 << FSM_CODE_TERMREQ)       \
                    101:        | (1 << FSM_CODE_TERMACK)       \
                    102:        | (1 << FSM_CODE_CODEREJ)       \
                    103:        | (1 << FSM_CODE_RESETREQ)      \
                    104:        | (1 << FSM_CODE_RESETACK)
                    105: 
                    106: /* FSM options descriptors */
                    107: static opt_pr_t        ppp_cpp_pr_mppc;
                    108: 
                    109: static const   struct ppp_fsm_optdesc ccp_opt_desc[] = {
                    110:        { "OUI",        CCP_OPT_OUI,    0, 255, 0,      NULL },
                    111:        { "Predictor-1",CCP_OPT_PRED1,  0, 255, 0,      NULL },
                    112:        { "Predictor-2",CCP_OPT_PRED2,  0, 255, 0,      NULL },
                    113:        { "Puddle",     CCP_OPT_PUDDLE, 0, 255, 0,      NULL },
                    114:        { "HWPPC",      CCP_OPT_HWPPC,  0, 255, 0,      NULL },
                    115:        { "Stac",       CCP_OPT_STAC,   0, 255, 0,      NULL },
                    116:        { "MPPC/MPPE",  CCP_OPT_MPPC,   4, 4,   1,      ppp_cpp_pr_mppc },
                    117:        { "Gandalf",    CCP_OPT_GAND,   0, 255, 0,      NULL },
                    118:        { "v.42bis",    CCP_OPT_V42BIS, 0, 255, 0,      NULL },
                    119:        { "BSD-LZW",    CCP_OPT_BSD,    0, 255, 0,      NULL },
                    120:        { "Deflate",    CCP_OPT_DEFLATE,0, 255, 0,      NULL },
                    121:        { NULL,         0,              0, 0,   0,      NULL }
                    122: };
                    123: 
                    124: /* FSM type for CCP */
                    125: static ppp_fsm_type_destroy_t          ppp_ccp_destroy;
                    126: static ppp_fsm_type_build_conf_req_t   ppp_ccp_build_conf_req;
                    127: static ppp_fsm_type_recv_conf_req_t    ppp_ccp_recv_conf_req;
                    128: static ppp_fsm_type_recv_conf_rej_t    ppp_ccp_recv_conf_rej;
                    129: static ppp_fsm_type_recv_conf_nak_t    ppp_ccp_recv_conf_nak;
                    130: static ppp_fsm_type_recv_reset_req_t   ppp_ccp_recv_reset_req;
                    131: static ppp_fsm_type_recv_reset_ack_t   ppp_ccp_recv_reset_ack;
                    132: 
                    133: const struct   ppp_fsm_type ppp_fsm_ccp = {
                    134:        "CCP",
                    135:        PPP_PROTO_CCP,
                    136:        CCP_SUPPORTED_CODES,
                    137:        CCP_REQUIRED_CODES,
                    138:        ccp_opt_desc,
                    139:        NULL,
                    140:        ppp_ccp_destroy,
                    141:        ppp_ccp_build_conf_req,
                    142:        ppp_ccp_recv_conf_req,
                    143:        ppp_ccp_recv_conf_rej,
                    144:        ppp_ccp_recv_conf_nak,
                    145:        NULL,
                    146:        ppp_ccp_recv_reset_req,
                    147:        ppp_ccp_recv_reset_ack,
                    148:        NULL
                    149: };
                    150: 
                    151: /* CCP instance state */
                    152: struct ccp {
                    153:        struct ppp_fsm_instance *inst;          /* backpointer to instance */
                    154:        struct ppp_ccp_config   conf;           /* initial config */
                    155:        struct ppp_ccp_req      req;            /* current request state */
                    156:        struct ppp_node         *node;          /* ng_ppp(4) node */
                    157: };
                    158: 
                    159: /* Internal functions */
                    160: static ppp_node_recvmsg_t      ppp_ccp_send_reset_req;
                    161: 
                    162: /***********************************************************************
                    163:                        PUBLIC FUNCTIONS
                    164: ***********************************************************************/
                    165: 
                    166: struct ppp_fsm_instance *
                    167: ppp_ccp_create(struct ppp_ccp_config *conf, struct ppp_node *node)
                    168: {
                    169:        struct ppp_fsm_instance *inst;
                    170:        struct ppp_ccp_req *req;
                    171:        struct ccp *ccp = NULL;
                    172: 
                    173:        /* Construct instance object */
                    174:        if ((inst = MALLOC(CCP_MTYPE, sizeof(*inst))) == NULL)
                    175:                return (NULL);
                    176:        memset(inst, 0, sizeof(*inst));
                    177:        inst->type = &ppp_fsm_ccp;
                    178: 
                    179:        /* Attach private data */
                    180:        if ((ccp = MALLOC(CCP_MTYPE, sizeof(*ccp))) == NULL)
                    181:                goto fail;
                    182:        memset(ccp, 0, sizeof(*ccp));
                    183:        ccp->conf = *conf;
                    184:        ccp->node = node;
                    185:        ccp->inst = inst;
                    186:        inst->arg = ccp;
                    187: 
                    188:        /* Initialize local request state */
                    189:        req = &ccp->req;
                    190:        req->mppc[PPP_SELF] = conf->mppc[PPP_SELF];
                    191:        req->mppe40[PPP_SELF] = conf->mppe40[PPP_SELF];
                    192:        req->mppe56[PPP_SELF] = conf->mppe56[PPP_SELF];
                    193:        req->mppe128[PPP_SELF] = conf->mppe128[PPP_SELF];
                    194:        req->mppe_stateless[PPP_SELF] = conf->mppe_stateless[PPP_SELF];
                    195: 
                    196:        /* Register handler for reset-req control message from ng_mppc(4) */
                    197:        if (ppp_node_set_recvmsg(ccp->node, NGM_MPPC_COOKIE,
                    198:            NGM_MPPC_RESETREQ, ppp_ccp_send_reset_req, ccp) == -1)
                    199:                goto fail;
                    200: 
                    201:        /* Done */
                    202:        return (inst);
                    203: 
                    204: fail:
                    205:        /* Clean up after failure */
                    206:        if (ccp != NULL)
                    207:                FREE(CCP_MTYPE, ccp);
                    208:        FREE(CCP_MTYPE, inst);
                    209:        return (NULL);
                    210: }
                    211: 
                    212: /*
                    213:  * Get CCP request state.
                    214:  */
                    215: void
                    216: ppp_ccp_get_req(struct ppp_fsm *fsm, struct ppp_ccp_req *req)
                    217: {
                    218:        struct ppp_fsm_instance *const inst = ppp_fsm_get_instance(fsm);
                    219:        struct ccp *const ccp = inst->arg;
                    220: 
                    221:        assert(inst->type == &ppp_fsm_ccp);
                    222:        memcpy(req, &ccp->req, sizeof(*req));
                    223: }
                    224: 
                    225: /***********************************************************************
                    226:                        FSM CALLBACKS
                    227: ***********************************************************************/
                    228: 
                    229: static void
                    230: ppp_ccp_destroy(struct ppp_fsm_instance *inst)
                    231: {
                    232:        struct ccp *const ccp = inst->arg;
                    233: 
                    234:        ppp_node_set_recvmsg(ccp->node,
                    235:            NGM_MPPC_COOKIE, NGM_MPPC_RESETREQ, NULL, NULL);
                    236:        FREE(CCP_MTYPE, ccp);
                    237:        FREE(CCP_MTYPE, inst);
                    238: }
                    239: 
                    240: static int
                    241: ppp_ccp_build_conf_req(struct ppp_fsm_instance *fsm,
                    242:        struct ppp_fsm_options *opts)
                    243: {
                    244:        struct ccp *const ccp = (struct ccp *)fsm->arg;
                    245:        struct ppp_ccp_req *const req = &ccp->req;
                    246:        u_int32_t mppo = 0;
                    247: 
                    248:        /* Add MPPC/MPPE requested config options */
                    249:        if (req->mppc[PPP_SELF])
                    250:                mppo |= MPPC_BIT;
                    251:        if (req->mppe40[PPP_SELF])
                    252:                mppo |= MPPE_40;
                    253:        if (req->mppe56[PPP_SELF])
                    254:                mppo |= MPPE_56;
                    255:        if (req->mppe128[PPP_SELF])
                    256:                mppo |= MPPE_128;
                    257:        if (req->mppe_stateless[PPP_SELF])
                    258:                mppo |= MPPE_STATELESS;
                    259: 
                    260:        /* If no options left to try, don't ask for anything */
                    261:        if ((mppo & (MPPC_BIT | MPPE_BITS)) == 0) {
                    262:                errno = EINVAL;
                    263:                return (-1);
                    264:        }
                    265: 
                    266:        /* Add option */
                    267:        mppo = htonl(mppo);
                    268:        if (ppp_fsm_option_add(opts, CCP_OPT_MPPC, 4, &mppo) == -1)
                    269:                return (-1);
                    270: 
                    271:        /* Done */
                    272:        return (0);
                    273: }
                    274: 
                    275: static int
                    276: ppp_ccp_recv_conf_req(struct ppp_fsm_instance *fsm,
                    277:        struct ppp_fsm_options *crq, struct ppp_fsm_options *nak,
                    278:        struct ppp_fsm_options *rej)
                    279: {
                    280:        struct ccp *const ccp = (struct ccp *)fsm->arg;
                    281:        struct ppp_ccp_config *const conf = &ccp->conf;
                    282:        struct ppp_ccp_req *const req = &ccp->req;
                    283:        int i;
                    284: 
                    285:        /* Initialize peer's request state */
                    286:        req->mppc[PPP_PEER] = 0;
                    287:        req->mppe40[PPP_PEER] = 0;
                    288:        req->mppe56[PPP_PEER] = 0;
                    289:        req->mppe128[PPP_PEER] = 0;
                    290:        req->mppe_stateless[PPP_PEER] = 0;
                    291: 
                    292:        /* Process options */
                    293:        for (i = 0; i < crq->num; i++) {
                    294:                const struct ppp_fsm_option *const opt = &crq->opts[i];
                    295: 
                    296:                switch (opt->type) {
                    297:                case CCP_OPT_MPPC:
                    298:                    {
                    299:                        u_int32_t obits;
                    300:                        u_int32_t bits;
                    301: 
                    302:                        /* Get requested bits */
                    303:                        memcpy(&obits, opt->data, 4);
                    304:                        obits = ntohl(obits);
                    305:                        bits = obits;
                    306: 
                    307:                        /* Filter out bits we can't handle */
                    308:                        bits &= MPPC_SUPPORTED;
                    309:                        if ((bits & MPPC_BIT) != 0 && !conf->mppc[PPP_PEER])
                    310:                                bits &= ~MPPC_BIT;
                    311:                        if ((bits & MPPE_40) != 0 && !conf->mppe40[PPP_PEER])
                    312:                                bits &= ~MPPE_40;
                    313:                        if ((bits & MPPE_56) != 0 && !conf->mppe56[PPP_PEER])
                    314:                                bits &= ~MPPE_56;
                    315:                        if ((bits & MPPE_128) != 0 && !conf->mppe128[PPP_PEER])
                    316:                                bits &= ~MPPE_128;
                    317:                        if ((bits & MPPE_STATELESS) != 0
                    318:                            && !conf->mppe_stateless[PPP_PEER])
                    319:                                bits &= ~MPPE_STATELESS;
                    320: 
                    321:                        /*
                    322:                         * It doesn't really make sense to do MPPE encryption
                    323:                         * in only one direction. Also, Win95/98 PPTP can't
                    324:                         * handle uni-directional encryption. So if the remote
                    325:                         * side doesn't request encryption, try to prompt it.
                    326:                         * This is broken wrt. normal PPP negotiation: typical
                    327:                         * Microsoft.
                    328:                         */
                    329:                        if ((bits & MPPE_BITS) == 0) {
                    330:                                if (req->mppe40[PPP_SELF])
                    331:                                        bits |= MPPE_40;
                    332:                                if (req->mppe56[PPP_SELF])
                    333:                                        bits |= MPPE_56;
                    334:                                if (req->mppe128[PPP_SELF])
                    335:                                        bits |= MPPE_128;
                    336:                        }
                    337: 
                    338:                        /* Make sure we're not left with no options */
                    339:                        if ((bits & MPPE_BITS) == 0) {
                    340:                                if (ccp->conf.mppe40[PPP_SELF])
                    341:                                        bits |= MPPE_40;
                    342:                                if (ccp->conf.mppe56[PPP_SELF])
                    343:                                        bits |= MPPE_56;
                    344:                                if (ccp->conf.mppe128[PPP_SELF])
                    345:                                        bits |= MPPE_128;
                    346:                        }
                    347: 
                    348:                        /* Now choose the strongest encryption available */
                    349:                        if ((bits & MPPE_128) != 0)
                    350:                                bits &= ~(MPPE_56|MPPE_40);
                    351:                        else if ((bits & MPPE_56) != 0)
                    352:                                bits &= ~(MPPE_128|MPPE_40);
                    353:                        else if ((bits & MPPE_40) != 0)
                    354:                                bits &= ~(MPPE_128|MPPE_56);
                    355: 
                    356:                        /* Send back a nak if there were any changes */
                    357:                        if (bits != obits) {
                    358:                                bits = htonl(bits);
                    359:                                if (ppp_fsm_option_add(nak,
                    360:                                    opt->type, 4, &bits) == -1)
                    361:                                        return (-1);
                    362:                                break;
                    363:                        }
                    364: 
                    365:                        /* Peer's request is accepted */
                    366:                        req->mppc[PPP_PEER] = (bits & MPPC_BIT) != 0;
                    367:                        req->mppe40[PPP_PEER] = (bits & MPPE_40) != 0;
                    368:                        req->mppe56[PPP_PEER] = (bits & MPPE_56) != 0;
                    369:                        req->mppe128[PPP_PEER] = (bits & MPPE_128) != 0;
                    370:                        req->mppe_stateless[PPP_PEER]
                    371:                            = (bits & MPPE_STATELESS) != 0;
                    372:                        break;
                    373:                    }
                    374:                default:
                    375:                        goto reject;
                    376:                }
                    377: 
                    378:                /* OK */
                    379:                continue;
                    380: 
                    381: reject:
                    382:                /* Reject this requested option */
                    383:                if (ppp_fsm_option_add(rej,
                    384:                    opt->type, opt->len, opt->data) == -1)
                    385:                        return (-1);
                    386:        }
                    387: 
                    388:        /* If there were no options, shut down */
                    389:        if (crq->num == 0) {
                    390:                errno = EINVAL;
                    391:                return (-1);
                    392:        }
                    393: 
                    394:        /* Done */
                    395:        return (0);
                    396: }
                    397: 
                    398: static int
                    399: ppp_ccp_recv_conf_rej(struct ppp_fsm_instance *fsm,
                    400:        struct ppp_fsm_options *rej)
                    401: {
                    402:        int i;
                    403: 
                    404:        for (i = 0; i < rej->num; i++) {
                    405:                const struct ppp_fsm_option *const opt = &rej->opts[i];
                    406: 
                    407:                switch (opt->type) {
                    408:                case CCP_OPT_MPPC:
                    409:                        errno = EINVAL;
                    410:                        return (-1);
                    411:                default:
                    412:                        break;
                    413:                }
                    414:        }
                    415: 
                    416:        /* Done */
                    417:        return (0);
                    418: }
                    419: 
                    420: static int
                    421: ppp_ccp_recv_conf_nak(struct ppp_fsm_instance *fsm,
                    422:        struct ppp_fsm_options *nak)
                    423: {
                    424:        struct ccp *const ccp = (struct ccp *)fsm->arg;
                    425:        struct ppp_ccp_req *const req = &ccp->req;
                    426:        int i;
                    427: 
                    428:        for (i = 0; i < nak->num; i++) {
                    429:                const struct ppp_fsm_option *const opt = &nak->opts[i];
                    430: 
                    431:                switch (opt->type) {
                    432:                case CCP_OPT_MPPC:
                    433:                    {
                    434:                        u_int32_t bits;
                    435: 
                    436:                        memcpy(&bits, opt->data, 4);
                    437:                        bits = ntohl(bits);
                    438: 
                    439:                        /* Mask away bits the client didn't like */
                    440:                        if ((bits & MPPC_BIT) == 0)
                    441:                                req->mppc[PPP_SELF] = 0;
                    442:                        if ((bits & MPPE_40) == 0)
                    443:                                req->mppe40[PPP_SELF] = 0;
                    444:                        if ((bits & MPPE_56) == 0)
                    445:                                req->mppe56[PPP_SELF] = 0;
                    446:                        if ((bits & MPPE_128) == 0)
                    447:                                req->mppe128[PPP_SELF] = 0;
                    448:                        if ((bits & MPPE_STATELESS) == 0)
                    449:                                req->mppe_stateless[PPP_SELF] = 0;
                    450: 
                    451:                        /* Make sure we're not left with no options */
                    452:                        if ((bits & MPPE_BITS) == 0) {
                    453:                                if (ccp->conf.mppe40[PPP_SELF])
                    454:                                        bits |= MPPE_40;
                    455:                                if (ccp->conf.mppe56[PPP_SELF])
                    456:                                        bits |= MPPE_56;
                    457:                                if (ccp->conf.mppe128[PPP_SELF])
                    458:                                        bits |= MPPE_128;
                    459:                        }
                    460:                        break;
                    461:                    }
                    462:                default:
                    463:                        break;
                    464:                }
                    465:        }
                    466: 
                    467:        /* Done */
                    468:        return (0);
                    469: }
                    470: 
                    471: /*
                    472:  * Receive a Reset-Req from peer. Relay request to the ng_mppc(4) node.
                    473:  */
                    474: static void
                    475: ppp_ccp_recv_reset_req(struct ppp_fsm_instance *fsm,
                    476:        const u_char *data, u_int len)
                    477: {
                    478:        struct ccp *const ccp = (struct ccp *)fsm->arg;
                    479: 
                    480:        ppp_node_send_msg(ccp->node, NG_PPP_HOOK_COMPRESS,
                    481:            NGM_MPPC_COOKIE, NGM_MPPC_RESETREQ, NULL, 0);
                    482: }
                    483: 
                    484: /*
                    485:  * Receive a Reset-Ack.
                    486:  */
                    487: static void
                    488: ppp_ccp_recv_reset_ack(struct ppp_fsm_instance *fsm,
                    489:        const u_char *data, u_int len)
                    490: {
                    491:        return;                 /* not used by MPPC/MPPE, just ignore it */
                    492: }
                    493: 
                    494: /***********************************************************************
                    495:                        INTERNAL FUNCTIONS
                    496: ***********************************************************************/
                    497: 
                    498: static void
                    499: ppp_ccp_send_reset_req(void *arg, struct ng_mesg *msg)
                    500: {
                    501:        struct ccp *const ccp = arg;
                    502:        struct ppp_fsm *const fsm = ccp->inst->fsm;
                    503: 
                    504:        ppp_fsm_send_reset_req(fsm, NULL, 0);
                    505: }
                    506: 
                    507: static void
                    508: ppp_cpp_pr_mppc(const struct ppp_fsm_optdesc *desc,
                    509:        const struct ppp_fsm_option *opt, char *buf, size_t bmax)
                    510: {
                    511:        static const struct {
                    512:                u_int32_t       bit;
                    513:                const char      *name;
                    514:        } mppe_bits[] = {
                    515:                { MPPC_BIT,             "MPPC" },
                    516:                { MPPE_BITS,            "MPPE" },
                    517:                { MPPE_40,              "40 bit" },
                    518:                { MPPE_56,              "56 bit" },
                    519:                { MPPE_128,             "128 bit" },
                    520:                { MPPE_STATELESS,       "stateless" },
                    521:                { 0 }
                    522:        };
                    523:        u_int32_t mppo;
                    524:        int first;
                    525:        int i;
                    526: 
                    527:        if (opt->len < 4) {
                    528:                snprintf(buf, bmax, "<truncated>");
                    529:                return;
                    530:        }
                    531:        memcpy(&mppo, opt->data, 4);
                    532:        mppo = ntohl(mppo);
                    533:        *buf = '\0';
                    534:        for (first = 1, i = 0; mppe_bits[i].bit != 0; i++) {
                    535:                if ((mppo & mppe_bits[i].bit) != 0) {
                    536:                        snprintf(buf + strlen(buf), bmax - strlen(buf),
                    537:                            "%s%s", first ? "" : ", ", mppe_bits[i].name);
                    538:                        first = 0;
                    539:                }
                    540:        }
                    541: }
                    542: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>