Annotation of embedaddon/libpdel/ppp/ppp_ipcp.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_ipcp.h"
                     47: 
                     48: /* Whether to do VJC compressed CID's */
                     49: #define IPCP_ALLOW_SELF_COMPCID        0       /* whether we allow to recv */
                     50: #define IPCP_ALLOW_PEER_COMPCID        1       /* whether we allow to send */
                     51: 
                     52: /* Memory type */
                     53: #define IPCP_MTYPE             "ipcp"
                     54: 
                     55: /* IPCP configuration options */
                     56: enum ipcp_option {
                     57:        IPCP_OPT_IP             =3,     /* ip address */
                     58:        IPCP_OPT_COMP           =2,     /* compression */
                     59:        IPCP_OPT_DNS1           =129,   /* primary dns */
                     60:        IPCP_OPT_DNS2           =131,   /* secondary dns */
                     61:        IPCP_OPT_NBNS1          =130,   /* primary nbns */
                     62:        IPCP_OPT_NBNS2          =132,   /* secondary nbns */
                     63: };
                     64: 
                     65: static const u_char ipcp_dns_opts[2] = { IPCP_OPT_DNS1, IPCP_OPT_DNS2 };
                     66: static const u_char ipcp_nbns_opts[2] = { IPCP_OPT_NBNS1, IPCP_OPT_NBNS2 };
                     67: 
                     68: /* Supported and required FSM codes */
                     69: #define IPCP_SUPPORTED_CODES           \
                     70:          (1 << FSM_CODE_CONFIGREQ)     \
                     71:        | (1 << FSM_CODE_CONFIGACK)     \
                     72:        | (1 << FSM_CODE_CONFIGNAK)     \
                     73:        | (1 << FSM_CODE_CONFIGREJ)     \
                     74:        | (1 << FSM_CODE_TERMREQ)       \
                     75:        | (1 << FSM_CODE_TERMACK)       \
                     76:        | (1 << FSM_CODE_CODEREJ)
                     77: #define IPCP_REQUIRED_CODES            \
                     78:          (1 << FSM_CODE_CONFIGREQ)     \
                     79:        | (1 << FSM_CODE_CONFIGACK)     \
                     80:        | (1 << FSM_CODE_CONFIGNAK)     \
                     81:        | (1 << FSM_CODE_CONFIGREJ)     \
                     82:        | (1 << FSM_CODE_TERMREQ)       \
                     83:        | (1 << FSM_CODE_TERMACK)       \
                     84:        | (1 << FSM_CODE_CODEREJ)
                     85: 
                     86: /* FSM options descriptors */
                     87: static opt_pr_t        ppp_ipcp_pr_ip;
                     88: static opt_pr_t        ppp_ipcp_pr_ipcomp;
                     89: 
                     90: static const   struct ppp_fsm_optdesc ipcp_opt_desc[] = {
                     91:        { "IP-Addr",    IPCP_OPT_IP,    4, 4,   1,      ppp_ipcp_pr_ip },
                     92:        { "IP-Comp",    IPCP_OPT_COMP,  4, 4,   1,      ppp_ipcp_pr_ipcomp },
                     93:        { "DNS1",       IPCP_OPT_DNS1,  4, 4,   1,      ppp_ipcp_pr_ip },
                     94:        { "DNS2",       IPCP_OPT_DNS2,  4, 4,   1,      ppp_ipcp_pr_ip },
                     95:        { "NBNS1",      IPCP_OPT_NBNS1, 4, 4,   1,      ppp_ipcp_pr_ip },
                     96:        { "NBNS2",      IPCP_OPT_NBNS2, 4, 4,   1,      ppp_ipcp_pr_ip },
                     97:        { NULL,         0,              0, 0,   0,      NULL }
                     98: };
                     99: 
                    100: /* FSM type for IPCP */
                    101: static ppp_fsm_type_destroy_t          ppp_ipcp_destroy;
                    102: static ppp_fsm_type_build_conf_req_t   ppp_ipcp_build_conf_req;
                    103: static ppp_fsm_type_recv_conf_req_t    ppp_ipcp_recv_conf_req;
                    104: static ppp_fsm_type_recv_conf_rej_t    ppp_ipcp_recv_conf_rej;
                    105: static ppp_fsm_type_recv_conf_nak_t    ppp_ipcp_recv_conf_nak;
                    106: 
                    107: const struct   ppp_fsm_type ppp_fsm_ipcp = {
                    108:        "IPCP",
                    109:        PPP_PROTO_IPCP,
                    110:        IPCP_SUPPORTED_CODES,
                    111:        IPCP_REQUIRED_CODES,
                    112:        ipcp_opt_desc,
                    113:        NULL,
                    114:        ppp_ipcp_destroy,
                    115:        ppp_ipcp_build_conf_req,
                    116:        ppp_ipcp_recv_conf_req,
                    117:        ppp_ipcp_recv_conf_rej,
                    118:        ppp_ipcp_recv_conf_nak,
                    119:        NULL,
                    120:        NULL,
                    121:        NULL,
                    122:        NULL
                    123: };
                    124: 
                    125: /* IPCP instance state */
                    126: struct ipcp {
                    127:        struct ppp_ipcp_config  conf;           /* initial config */
                    128:        struct ppp_ipcp_req     req;            /* current request state */
                    129:        struct ppp_node         *node;          /* ng_ppp(4) node */
                    130: };
                    131: 
                    132: /* VJC compression header */
                    133: struct ipcp_vjc {
                    134:        u_int16_t       proto;
                    135:        u_char          maxchan;
                    136:        u_char          compcid;
                    137: };
                    138: 
                    139: /***********************************************************************
                    140:                        PUBLIC FUNCTIONS
                    141: ***********************************************************************/
                    142: 
                    143: struct ppp_fsm_instance *
                    144: ppp_ipcp_create(struct ppp_ipcp_config *conf, struct ppp_node *node)
                    145: {
                    146:        struct ppp_fsm_instance *inst;
                    147:        struct ppp_ipcp_req *req;
                    148:        struct ipcp *ipcp = NULL;
                    149: 
                    150:        /* Construct instance object */
                    151:        if ((inst = MALLOC(IPCP_MTYPE, sizeof(*inst))) == NULL)
                    152:                return (NULL);
                    153:        memset(inst, 0, sizeof(*inst));
                    154:        inst->type = &ppp_fsm_ipcp;
                    155: 
                    156:        /* Attach private data */
                    157:        if ((ipcp = MALLOC(IPCP_MTYPE, sizeof(*ipcp))) == NULL)
                    158:                goto fail;
                    159:        memset(ipcp, 0, sizeof(*ipcp));
                    160:        ipcp->conf = *conf;
                    161:        ipcp->node = node;
                    162:        inst->arg = ipcp;
                    163: 
                    164:        /* Initialize local request state */
                    165:        req = &ipcp->req;
                    166:        req->ip[PPP_SELF] = conf->ip[PPP_SELF];
                    167:        req->vjc[PPP_SELF].enabled = 1;
                    168:        req->vjc[PPP_SELF].maxchan = NG_VJC_MAX_CHANNELS - 1;
                    169:        req->vjc[PPP_SELF].compcid = IPCP_ALLOW_SELF_COMPCID;
                    170:        req->ask_dns = conf->do_dns[PPP_SELF];
                    171:        req->ask_nbns = conf->do_nbns[PPP_SELF];
                    172: 
                    173:        /* Done */
                    174:        return (inst);
                    175: 
                    176: fail:
                    177:        /* Clean up after failure */
                    178:        if (ipcp != NULL)
                    179:                FREE(IPCP_MTYPE, ipcp);
                    180:        FREE(IPCP_MTYPE, inst);
                    181:        return (NULL);
                    182: }
                    183: 
                    184: /*
                    185:  * Get IPCP request state.
                    186:  */
                    187: void
                    188: ppp_ipcp_get_req(struct ppp_fsm *fsm, struct ppp_ipcp_req *req)
                    189: {
                    190:        struct ppp_fsm_instance *const inst = ppp_fsm_get_instance(fsm);
                    191:        struct ipcp *const ipcp = inst->arg;
                    192: 
                    193:        assert(inst->type == &ppp_fsm_ipcp);
                    194:        memcpy(req, &ipcp->req, sizeof(*req));
                    195: }
                    196: 
                    197: /***********************************************************************
                    198:                        FSM CALLBACKS
                    199: ***********************************************************************/
                    200: 
                    201: static void
                    202: ppp_ipcp_destroy(struct ppp_fsm_instance *inst)
                    203: {
                    204:        struct ipcp *const ipcp = inst->arg;
                    205: 
                    206:        FREE(IPCP_MTYPE, ipcp);
                    207:        FREE(IPCP_MTYPE, inst);
                    208: }
                    209: 
                    210: static int
                    211: ppp_ipcp_build_conf_req(struct ppp_fsm_instance *fsm,
                    212:        struct ppp_fsm_options *opts)
                    213: {
                    214:        struct ipcp *const ipcp = (struct ipcp *)fsm->arg;
                    215:        struct ppp_ipcp_req *const req = &ipcp->req;
                    216:        int i;
                    217: 
                    218:        /* Add requested config options */
                    219:        if (ppp_fsm_option_add(opts, IPCP_OPT_IP, 4, &req->ip[PPP_SELF]) == -1)
                    220:                return (-1);
                    221:        if (req->vjc[PPP_SELF].enabled) {
                    222:                struct ipcp_vjc vjc;
                    223: 
                    224:                vjc.proto = htons(PPP_PROTO_VJCOMP);
                    225:                vjc.maxchan = req->vjc[PPP_SELF].maxchan;
                    226:                vjc.compcid = req->vjc[PPP_SELF].compcid;
                    227:                if (ppp_fsm_option_add(opts,
                    228:                    IPCP_OPT_COMP, sizeof(vjc), &vjc) == -1)
                    229:                        return (-1);
                    230:        }
                    231:        if (req->ask_dns) {
                    232:                for (i = 0; i < 2; i++) {
                    233:                        if (ppp_fsm_option_add(opts,
                    234:                            ipcp_dns_opts[i], 4, &req->dns[i]) == -1)
                    235:                                return (-1);
                    236:                }
                    237:        }
                    238:        if (req->ask_nbns) {
                    239:                for (i = 0; i < 2; i++) {
                    240:                        if (ppp_fsm_option_add(opts,
                    241:                            ipcp_nbns_opts[i], 4, &req->nbns[i]) == -1)
                    242:                                return (-1);
                    243:                }
                    244:        }
                    245: 
                    246:        /* Done */
                    247:        return (0);
                    248: }
                    249: 
                    250: static int
                    251: ppp_ipcp_recv_conf_req(struct ppp_fsm_instance *fsm,
                    252:        struct ppp_fsm_options *crq, struct ppp_fsm_options *nak,
                    253:        struct ppp_fsm_options *rej)
                    254: {
                    255:        struct ipcp *const ipcp = (struct ipcp *)fsm->arg;
                    256:        struct ppp_ipcp_config *const conf = &ipcp->conf;
                    257:        struct ppp_ipcp_req *const req = &ipcp->req;
                    258:        int saw_ip = 0;
                    259:        int i;
                    260: 
                    261:        /* Initialize peer's request state */
                    262:        req->ip[PPP_PEER].s_addr = 0;
                    263:        memset(&req->vjc[PPP_PEER], 0, sizeof(req->vjc[PPP_PEER]));
                    264: 
                    265:        /* Process options */
                    266:        for (i = 0; i < crq->num; i++) {
                    267:                const struct ppp_fsm_option *const opt = &crq->opts[i];
                    268: 
                    269:                switch (opt->type) {
                    270:                case IPCP_OPT_IP:
                    271:                    {
                    272:                        struct in_addr ip;
                    273: 
                    274:                        saw_ip = 1;
                    275:                        memcpy(&ip, opt->data, 4);
                    276:                        if ((ip.s_addr & conf->mask[PPP_PEER].s_addr)
                    277:                            != (conf->ip[PPP_PEER].s_addr
                    278:                              & conf->mask[PPP_PEER].s_addr)) {
                    279:                                if (ppp_fsm_option_add(nak, opt->type,
                    280:                                    4, &conf->ip[PPP_PEER]) == -1)
                    281:                                        return (-1);
                    282:                                break;
                    283:                        }
                    284:                        req->ip[PPP_PEER] = ip;
                    285:                        break;
                    286:                    }
                    287:                case IPCP_OPT_COMP:
                    288:                    {
                    289:                        struct ipcp_vjc vjc;
                    290:                        int nakit = 0;
                    291: 
                    292:                        memcpy(&vjc, opt->data, sizeof(vjc));
                    293:                        if (ntohs(vjc.proto) != PPP_PROTO_VJCOMP)
                    294:                                goto reject;
                    295:                        if (vjc.maxchan < NG_VJC_MIN_CHANNELS - 1) {
                    296:                                vjc.maxchan = NG_VJC_MIN_CHANNELS - 1;
                    297:                                nakit = 1;
                    298:                        }
                    299:                        if (vjc.maxchan > NG_VJC_MAX_CHANNELS - 1) {
                    300:                                vjc.maxchan = NG_VJC_MAX_CHANNELS - 1;
                    301:                                nakit = 1;
                    302:                        }
                    303: #if !IPCP_ALLOW_PEER_COMPCID
                    304:                        if (vjc.compcid) {
                    305:                                vjc.compcid = 0;
                    306:                                nakit = 1;
                    307:                        }
                    308: #endif
                    309:                        if (nakit) {
                    310:                                if (ppp_fsm_option_add(nak,
                    311:                                    opt->type, sizeof(vjc), &vjc) == -1)
                    312:                                        return (-1);
                    313:                                break;
                    314:                        }
                    315:                        req->vjc[PPP_PEER].enabled = 1;
                    316:                        req->vjc[PPP_PEER].maxchan = vjc.maxchan;
                    317:                        req->vjc[PPP_PEER].compcid = vjc.compcid;
                    318:                        break;
                    319:                    }
                    320:                case IPCP_OPT_DNS1:
                    321:                case IPCP_OPT_DNS2:
                    322:                    {
                    323:                        const int i = (opt->type == IPCP_OPT_DNS2);
                    324:                        struct in_addr ip;
                    325: 
                    326:                        if (!conf->do_dns[PPP_PEER]
                    327:                            || conf->dns[i].s_addr == 0)
                    328:                                goto reject;
                    329:                        memcpy(&ip, opt->data, 4);
                    330:                        if (ip.s_addr != conf->dns[i].s_addr) {
                    331:                                if (ppp_fsm_option_add(nak, opt->type,
                    332:                                    4, &conf->dns[i]) == -1)
                    333:                                        return (-1);
                    334:                                break;
                    335:                        }
                    336:                        break;
                    337:                    }
                    338:                case IPCP_OPT_NBNS1:
                    339:                case IPCP_OPT_NBNS2:
                    340:                    {
                    341:                        const int i = (opt->type == IPCP_OPT_NBNS2);
                    342:                        struct in_addr ip;
                    343: 
                    344:                        if (!conf->do_nbns[PPP_PEER]
                    345:                            || conf->nbns[i].s_addr == 0)
                    346:                                goto reject;
                    347:                        memcpy(&ip, opt->data, 4);
                    348:                        if (ip.s_addr != conf->nbns[i].s_addr) {
                    349:                                if (ppp_fsm_option_add(nak, opt->type,
                    350:                                    4, &conf->nbns[i]) == -1)
                    351:                                        return (-1);
                    352:                                break;
                    353:                        }
                    354:                        break;
                    355:                    }
                    356:                default:
                    357:                        goto reject;
                    358:                }
                    359: 
                    360:                /* OK */
                    361:                continue;
                    362: 
                    363: reject:
                    364:                /* Reject this requested option */
                    365:                if (ppp_fsm_option_add(rej,
                    366:                    opt->type, opt->len, opt->data) == -1)
                    367:                        return (-1);
                    368:        }
                    369: 
                    370:        /* Make sure we saw an IP address option */
                    371:        if (!saw_ip) {
                    372:                errno = EINVAL;
                    373:                return (-1);
                    374:        }
                    375: 
                    376:        /* Done */
                    377:        return (0);
                    378: }
                    379: 
                    380: static int
                    381: ppp_ipcp_recv_conf_rej(struct ppp_fsm_instance *fsm,
                    382:        struct ppp_fsm_options *rej)
                    383: {
                    384:        struct ipcp *const ipcp = (struct ipcp *)fsm->arg;
                    385:        struct ppp_ipcp_req *const req = &ipcp->req;
                    386:        int i;
                    387: 
                    388:        for (i = 0; i < rej->num; i++) {
                    389:                const struct ppp_fsm_option *const opt = &rej->opts[i];
                    390: 
                    391:                switch (opt->type) {
                    392:                case IPCP_OPT_IP:
                    393:                        errno = EINVAL;
                    394:                        return (-1);
                    395:                case IPCP_OPT_COMP:
                    396:                        req->vjc[PPP_SELF].enabled = 0;
                    397:                        break;
                    398:                case IPCP_OPT_DNS1:
                    399:                case IPCP_OPT_DNS2:
                    400:                        req->ask_dns = 0;
                    401:                        break;
                    402:                case IPCP_OPT_NBNS1:
                    403:                case IPCP_OPT_NBNS2:
                    404:                        req->ask_nbns = 0;
                    405:                        break;
                    406:                default:
                    407:                        break;
                    408:                }
                    409:        }
                    410: 
                    411:        /* Done */
                    412:        return (0);
                    413: }
                    414: 
                    415: static int
                    416: ppp_ipcp_recv_conf_nak(struct ppp_fsm_instance *fsm,
                    417:        struct ppp_fsm_options *nak)
                    418: {
                    419:        struct ipcp *const ipcp = (struct ipcp *)fsm->arg;
                    420:        struct ppp_ipcp_config *const conf = &ipcp->conf;
                    421:        struct ppp_ipcp_req *const req = &ipcp->req;
                    422:        int i;
                    423: 
                    424:        for (i = 0; i < nak->num; i++) {
                    425:                const struct ppp_fsm_option *const opt = &nak->opts[i];
                    426: 
                    427:                switch (opt->type) {
                    428:                case IPCP_OPT_IP:
                    429:                    {
                    430:                        struct in_addr ip;
                    431: 
                    432:                        memcpy(&ip, opt->data, 4);
                    433:                        if ((ip.s_addr & conf->mask[PPP_SELF].s_addr)
                    434:                            != (conf->ip[PPP_SELF].s_addr
                    435:                              & conf->mask[PPP_SELF].s_addr))
                    436:                                break;
                    437:                        req->ip[PPP_SELF] = ip;
                    438:                        break;
                    439:                    }
                    440:                case IPCP_OPT_COMP:
                    441:                    {
                    442:                        struct ipcp_vjc vjc;
                    443: 
                    444:                        memcpy(&vjc, opt->data, sizeof(vjc));
                    445:                        if (ntohs(vjc.proto) != PPP_PROTO_VJCOMP)
                    446:                                break;
                    447:                        if (vjc.maxchan < NG_VJC_MIN_CHANNELS - 1)
                    448:                                vjc.maxchan = NG_VJC_MIN_CHANNELS - 1;
                    449:                        if (vjc.maxchan > NG_VJC_MAX_CHANNELS - 1)
                    450:                                vjc.maxchan = NG_VJC_MAX_CHANNELS - 1;
                    451:                        req->vjc[PPP_SELF].maxchan = vjc.maxchan;
                    452: #if IPCP_ALLOW_SELF_COMPCID
                    453:                        if (vjc.compcid)
                    454:                                req->vjc[PPP_SELF].compcid = 1;
                    455: #endif
                    456:                        break;
                    457:                    }
                    458:                case IPCP_OPT_DNS1:
                    459:                case IPCP_OPT_DNS2:
                    460:                    {
                    461:                        const int i = (opt->type == IPCP_OPT_DNS2);
                    462: 
                    463:                        memcpy(&req->dns[i], opt->data, 4);
                    464:                        break;
                    465:                    }
                    466:                case IPCP_OPT_NBNS1:
                    467:                case IPCP_OPT_NBNS2:
                    468:                    {
                    469:                        const int i = (opt->type == IPCP_OPT_NBNS2);
                    470: 
                    471:                        memcpy(&req->nbns[i], opt->data, 4);
                    472:                        break;
                    473:                    }
                    474:                default:
                    475:                        break;
                    476:                }
                    477:        }
                    478: 
                    479:        /* Done */
                    480:        return (0);
                    481: }
                    482: 
                    483: /***********************************************************************
                    484:                        INTERNAL FUNCTIONS
                    485: ***********************************************************************/
                    486: 
                    487: static void
                    488: ppp_ipcp_pr_ip(const struct ppp_fsm_optdesc *desc,
                    489:        const struct ppp_fsm_option *opt, char *buf, size_t bmax)
                    490: {
                    491:        struct in_addr ip;
                    492: 
                    493:        if (opt->len < 4) {
                    494:                snprintf(buf, bmax, "<truncated>");
                    495:                return;
                    496:        }
                    497:        memcpy(&ip, opt->data, 4);
                    498:        snprintf(buf, bmax, "%s", inet_ntoa(ip));
                    499: }
                    500: 
                    501: static void
                    502: ppp_ipcp_pr_ipcomp(const struct ppp_fsm_optdesc *desc,
                    503:        const struct ppp_fsm_option *opt, char *buf, size_t bmax)
                    504: {
                    505:        struct ipcp_vjc vjc;
                    506: 
                    507:        if (opt->len < 2) {
                    508:                snprintf(buf, bmax, "<truncated>");
                    509:                return;
                    510:        }
                    511:        memcpy(&vjc, opt->data, 2);
                    512:        if (ntohs(vjc.proto) != PPP_PROTO_VJCOMP) {
                    513:                snprintf(buf, bmax, "?0x%04x", ntohs(vjc.proto));
                    514:                return;
                    515:        }
                    516:        if (opt->len < sizeof(vjc)) {
                    517:                snprintf(buf, bmax, "VJCOMP %s", "<truncated>");
                    518:                return;
                    519:        }
                    520:        memcpy(&vjc, opt->data, sizeof(vjc));
                    521:        snprintf(buf, bmax, "VJCOMP %d channels, %s comp-cid",
                    522:            vjc.maxchan + 1, vjc.compcid ? "allow" : "no");
                    523: }
                    524: 

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