Module Name: src Committed By: yamaguchi Date: Wed Nov 25 10:03:39 UTC 2020
Modified Files: src/sys/net: if_spppsubr.c Log Message: change function name(RCR => parse_confreq) reviewed by knakahara@n.o. To generate a diff of this commit: cvs rdiff -u -r1.204 -r1.205 src/sys/net/if_spppsubr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/if_spppsubr.c diff -u src/sys/net/if_spppsubr.c:1.204 src/sys/net/if_spppsubr.c:1.205 --- src/sys/net/if_spppsubr.c:1.204 Wed Nov 25 09:59:52 2020 +++ src/sys/net/if_spppsubr.c Wed Nov 25 10:03:38 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if_spppsubr.c,v 1.204 2020/11/25 09:59:52 yamaguchi Exp $ */ +/* $NetBSD: if_spppsubr.c,v 1.205 2020/11/25 10:03:38 yamaguchi Exp $ */ /* * Synchronous PPP/Cisco link level subroutines. @@ -41,7 +41,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.204 2020/11/25 09:59:52 yamaguchi Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.205 2020/11/25 10:03:38 yamaguchi Exp $"); #if defined(_KERNEL_OPT) #include "opt_inet.h" @@ -197,6 +197,15 @@ __KERNEL_RCSID(0, "$NetBSD: if_spppsubr. #define STATE_ACK_SENT 8 #define STATE_OPENED 9 +enum cp_rcr_type { + CP_RCR_NONE = 0, /* initial value */ + CP_RCR_ACK, /* RCR+ */ + CP_RCR_NAK, /* RCR- */ + CP_RCR_REJ, /* RCR- */ + CP_RCR_DROP, /* DROP message */ + CP_RCR_ERR, /* internal error */ +}; + struct ppp_header { uint8_t address; uint8_t control; @@ -242,9 +251,6 @@ struct cp { void (*Open)(struct sppp *, void *); void (*Close)(struct sppp *, void *); void (*TO)(struct sppp *, void *); - int (*RCR)(struct sppp *, struct lcp_header *, int); - void (*RCN_rej)(struct sppp *, struct lcp_header *, int); - void (*RCN_nak)(struct sppp *, struct lcp_header *, int); /* actions */ void (*tlu)(struct sppp *); void (*tld)(struct sppp *); @@ -252,6 +258,13 @@ struct cp { void (*tlf)(const struct cp *, struct sppp *); void (*scr)(struct sppp *); void (*scan)(const struct cp *, struct sppp *); + + /* message parser */ + enum cp_rcr_type + (*parse_confreq)(struct sppp *, struct lcp_header *, int, + uint8_t **, size_t *, size_t *); + void (*parse_confrej)(struct sppp *, struct lcp_header *, int); + void (*parse_confnak)(struct sppp *, struct lcp_header *, int); }; enum auth_role { @@ -357,9 +370,11 @@ static void sppp_lcp_init(struct sppp *) static void sppp_lcp_up(struct sppp *, void *); static void sppp_lcp_down(struct sppp *, void *); static void sppp_lcp_open(struct sppp *, void *); -static int sppp_lcp_RCR(struct sppp *, struct lcp_header *, int); -static void sppp_lcp_RCN_rej(struct sppp *, struct lcp_header *, int); -static void sppp_lcp_RCN_nak(struct sppp *, struct lcp_header *, int); +static enum cp_rcr_type + sppp_lcp_confreq(struct sppp *, struct lcp_header *, int, + uint8_t **, size_t *, size_t *); +static void sppp_lcp_confrej(struct sppp *, struct lcp_header *, int); +static void sppp_lcp_confnak(struct sppp *, struct lcp_header *, int); static void sppp_lcp_tlu(struct sppp *); static void sppp_lcp_tld(struct sppp *); static void sppp_lcp_tls(const struct cp *, struct sppp *); @@ -371,17 +386,21 @@ static int sppp_cp_check(struct sppp *, static void sppp_ipcp_init(struct sppp *); static void sppp_ipcp_open(struct sppp *, void *); static void sppp_ipcp_close(struct sppp *, void *); -static int sppp_ipcp_RCR(struct sppp *, struct lcp_header *, int); -static void sppp_ipcp_RCN_rej(struct sppp *, struct lcp_header *, int); -static void sppp_ipcp_RCN_nak(struct sppp *, struct lcp_header *, int); +static enum cp_rcr_type + sppp_ipcp_confreq(struct sppp *, struct lcp_header *, int, + uint8_t **, size_t *, size_t *); +static void sppp_ipcp_confrej(struct sppp *, struct lcp_header *, int); +static void sppp_ipcp_confnak(struct sppp *, struct lcp_header *, int); static void sppp_ipcp_tlu(struct sppp *); static void sppp_ipcp_scr(struct sppp *); static void sppp_ipv6cp_init(struct sppp *); static void sppp_ipv6cp_open(struct sppp *, void *); -static int sppp_ipv6cp_RCR(struct sppp *, struct lcp_header *, int); -static void sppp_ipv6cp_RCN_rej(struct sppp *, struct lcp_header *, int); -static void sppp_ipv6cp_RCN_nak(struct sppp *, struct lcp_header *, int); +static enum cp_rcr_type + sppp_ipv6cp_confreq(struct sppp *, struct lcp_header *, int, + uint8_t **, size_t *, size_t *); +static void sppp_ipv6cp_confrej(struct sppp *, struct lcp_header *, int); +static void sppp_ipv6cp_confnak(struct sppp *, struct lcp_header *, int); static void sppp_ipv6cp_tlu(struct sppp *); static void sppp_ipv6cp_scr(struct sppp *); @@ -447,10 +466,11 @@ static void sppp_notify_chg_wlocked(stru /* our control protocol descriptors */ static const struct cp lcp = { PPP_LCP, IDX_LCP, CP_LCP, "lcp", - sppp_lcp_up, sppp_lcp_down, sppp_lcp_open, sppp_close_event, - sppp_to_event, sppp_lcp_RCR, sppp_lcp_RCN_rej, sppp_lcp_RCN_nak, - sppp_lcp_tlu, sppp_lcp_tld, sppp_lcp_tls, sppp_lcp_tlf, - sppp_lcp_scr, sppp_sca_scn + sppp_lcp_up, sppp_lcp_down, sppp_lcp_open, + sppp_close_event, sppp_to_event, + sppp_lcp_tlu, sppp_lcp_tld, sppp_lcp_tls, + sppp_lcp_tlf, sppp_lcp_scr, sppp_sca_scn, + sppp_lcp_confreq, sppp_lcp_confrej, sppp_lcp_confnak }; static const struct cp ipcp = { @@ -461,10 +481,11 @@ static const struct cp ipcp = { 0, #endif "ipcp", - sppp_up_event, sppp_down_event, sppp_ipcp_open, sppp_ipcp_close, - sppp_to_event, sppp_ipcp_RCR, sppp_ipcp_RCN_rej, sppp_ipcp_RCN_nak, - sppp_ipcp_tlu, sppp_null, sppp_tls, sppp_tlf, - sppp_ipcp_scr, sppp_sca_scn + sppp_up_event, sppp_down_event, sppp_ipcp_open, + sppp_ipcp_close, sppp_to_event, + sppp_ipcp_tlu, sppp_null, sppp_tls, + sppp_tlf, sppp_ipcp_scr, sppp_sca_scn, + sppp_ipcp_confreq, sppp_ipcp_confrej, sppp_ipcp_confnak, }; static const struct cp ipv6cp = { @@ -475,26 +496,29 @@ static const struct cp ipv6cp = { 0, #endif "ipv6cp", - sppp_up_event, sppp_down_event, sppp_ipv6cp_open, sppp_close_event, - sppp_to_event, sppp_ipv6cp_RCR, sppp_ipv6cp_RCN_rej, sppp_ipv6cp_RCN_nak, - sppp_ipv6cp_tlu, sppp_null, sppp_tls, sppp_tlf, - sppp_ipv6cp_scr, sppp_sca_scn + sppp_up_event, sppp_down_event, sppp_ipv6cp_open, + sppp_close_event, sppp_to_event, + sppp_ipv6cp_tlu, sppp_null, sppp_tls, + sppp_tlf, sppp_ipv6cp_scr, sppp_sca_scn, + sppp_ipv6cp_confreq, sppp_ipv6cp_confrej, sppp_ipv6cp_confnak, }; static const struct cp pap = { PPP_PAP, IDX_PAP, CP_AUTH, "pap", - sppp_up_event, sppp_down_event, sppp_open_event, sppp_close_event, - sppp_to_event, 0, 0, 0, + sppp_up_event, sppp_down_event, sppp_open_event, + sppp_close_event, sppp_to_event, sppp_pap_tlu, sppp_null, sppp_tls, sppp_tlf, - sppp_pap_scr, sppp_auth_sca_scn + sppp_pap_scr, sppp_auth_sca_scn, + NULL, NULL, NULL }; static const struct cp chap = { PPP_CHAP, IDX_CHAP, CP_AUTH, "chap", - sppp_up_event, sppp_down_event, sppp_chap_open, sppp_close_event, - sppp_auth_to_event, 0, 0, 0, + sppp_up_event, sppp_down_event, sppp_chap_open, + sppp_close_event, sppp_auth_to_event, sppp_chap_tlu, sppp_null, sppp_tls, sppp_tlf, - sppp_chap_scr, sppp_auth_sca_scn + sppp_chap_scr, sppp_auth_sca_scn, + NULL, NULL, NULL }; static const struct cp *cps[IDX_COUNT] = { @@ -1593,9 +1617,11 @@ sppp_cp_input(const struct cp *cp, struc STDDCL; struct lcp_header *h; int printlen, len = m->m_pkthdr.len; - int rv; + enum cp_rcr_type type; + size_t blen, rlen; u_char *p; uint32_t u32; + uint8_t *buf; SPPP_LOCK(sp, RW_WRITER); @@ -1634,16 +1660,33 @@ sppp_cp_input(const struct cp *cp, struc if_statinc(ifp, if_ierrors); break; } - rv = (cp->RCR)(sp, h, len); - if (rv < 0) { + + buf = NULL; + blen = 0; + rlen = 0; + + type = (cp->parse_confreq)(sp, h, len, + &buf, &blen, &rlen); + + if (type == CP_RCR_ERR) { /* fatal error, shut down */ - (cp->tld)(sp); - lcp.tlf(&lcp, sp); - SPPP_UNLOCK(sp); - return; + sppp_wq_add(sp->wq_cp, &sp->scp[IDX_LCP].work_close); + sppp_wq_add(sp->wq_cp, &sp->scp[IDX_LCP].work_open); + } else if (buf != NULL) { + if (sp->scp[cp->protoidx].rcr_buf != NULL) { + kmem_intr_free(sp->scp[cp->protoidx].rcr_buf, + sp->scp[cp->protoidx].rcr_blen); + } + + sp->scp[cp->protoidx].rcr_buf = (void *)buf; + buf = NULL; + + sp->scp[cp->protoidx].rcr_blen = blen; + sp->scp[cp->protoidx].rcr_rlen = rlen; + sp->scp[cp->protoidx].rcr_type = type; + sp->scp[cp->protoidx].rconfid = h->ident; + sppp_wq_add(sp->wq_cp, &sp->scp[cp->protoidx].work_rcr); } - sp->scp[cp->protoidx].rconfid = h->ident; - sppp_wq_add(sp->wq_cp, &sp->scp[cp->protoidx].work_rcr); break; case CONF_ACK: if (h->ident != sp->scp[cp->protoidx].confid) { @@ -1667,9 +1710,9 @@ sppp_cp_input(const struct cp *cp, struc break; } if (h->type == CONF_NAK) - (cp->RCN_nak)(sp, h, len); + (cp->parse_confnak)(sp, h, len); else /* CONF_REJ */ - (cp->RCN_rej)(sp, h, len); + (cp->parse_confrej)(sp, h, len); sppp_wq_add(sp->wq_cp, &sp->scp[cp->protoidx].work_rcn); break; @@ -2049,7 +2092,7 @@ static void sppp_rcr_event(struct sppp *sp, void *xcp) { const struct cp *cp = xcp; - u_char type; + enum cp_rcr_type type; void *buf; size_t blen; STDDCL; @@ -2058,7 +2101,7 @@ sppp_rcr_event(struct sppp *sp, void *xc buf = sp->scp[cp->protoidx].rcr_buf; blen = sp->scp[cp->protoidx].rcr_blen; - if (type == CONF_ACK) { + if (type == CP_RCR_ACK) { /* RCR+ event */ switch (sp->scp[cp->protoidx].state) { case STATE_OPENED: @@ -2512,11 +2555,13 @@ sppp_lcp_open(struct sppp *sp, void *xcp * caused action scn. (The return value is used to make the state * transition decision in the state automaton.) */ -static int -sppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int origlen) +static enum cp_rcr_type +sppp_lcp_confreq(struct sppp *sp, struct lcp_header *h, int origlen, + uint8_t **msgbuf, size_t *buflen, size_t *msglen) { STDDCL; - u_char *buf, *r, *p, l, blen, type; + u_char *buf, *r, *p, l, blen; + enum cp_rcr_type type; int len, rlen; uint32_t nmagic; u_short authproto; @@ -2524,19 +2569,20 @@ sppp_lcp_RCR(struct sppp *sp, struct lcp KASSERT(SPPP_WLOCKED(sp)); if (origlen < sizeof(*h)) - return 0; + return CP_RCR_DROP; origlen -= sizeof(*h); + type = CP_RCR_NONE; type = 0; if (origlen <= 0) - return 0; + return CP_RCR_DROP; else blen = origlen; buf = kmem_intr_alloc(blen, KM_NOSLEEP); if (buf == NULL) - return 0; + return CP_RCR_DROP; if (debug) log(LOG_DEBUG, "%s: lcp parse opts:", @@ -2560,7 +2606,7 @@ sppp_lcp_RCR(struct sppp *sp, struct lcp addlog("%s: received malicious LCP option 0x%02x, " "length 0x%02x, (len: 0x%02x) dropping.\n", ifp->if_xname, p[0], l, len); - rlen = -1; + type = CP_RCR_ERR; goto end; } if (debug) @@ -2655,7 +2701,7 @@ sppp_lcp_RCR(struct sppp *sp, struct lcp } if (rlen > 0) { - type = CONF_REJ; + type = CP_RCR_REJ; goto end; } @@ -2809,12 +2855,12 @@ sppp_lcp_RCR(struct sppp *sp, struct lcp if (debug) addlog(" max_failure (%d) exceeded, ", sp->lcp.max_failure); - type = CONF_REJ; + type = CP_RCR_REJ; } else { - type = CONF_NAK; + type = CP_RCR_NAK; } } else { - type = CONF_ACK; + type = CP_RCR_ACK; rlen = origlen; memcpy(r, h + 1, rlen); sp->scp[IDX_LCP].fail_counter = 0; @@ -2825,26 +2871,16 @@ end: if (debug) addlog("\n"); - if (sp->scp[IDX_LCP].rcr_buf != NULL) { - kmem_intr_free(sp->scp[IDX_LCP].rcr_buf, - sp->scp[IDX_LCP].rcr_blen); - } - - if (rlen < 0) { - kmem_intr_free(buf, blen); - sp->scp[IDX_IPCP].rcr_buf = NULL; - sp->scp[IDX_IPCP].rcr_rlen = 0; - return -1; - } - - sp->scp[IDX_LCP].rcr_type = type; - sp->scp[IDX_LCP].rcr_buf = buf; - sp->scp[IDX_LCP].rcr_blen = blen; - sp->scp[IDX_LCP].rcr_rlen = rlen; - - if (type != CONF_ACK) - return 0; - return 1; + if (type == CP_RCR_ERR || type == CP_RCR_DROP) { + if (buf != NULL) + kmem_intr_free(buf, blen); + } else { + *msgbuf = buf; + *buflen = blen; + *msglen = rlen; + } + + return type; } /* @@ -2852,7 +2888,7 @@ end: * negotiation. */ static void -sppp_lcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len) +sppp_lcp_confrej(struct sppp *sp, struct lcp_header *h, int len) { STDDCL; u_char *p, l; @@ -2934,7 +2970,7 @@ end: * negotiation. */ static void -sppp_lcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len) +sppp_lcp_confnak(struct sppp *sp, struct lcp_header *h, int len) { STDDCL; u_char *p, l; @@ -3319,21 +3355,23 @@ sppp_ipcp_close(struct sppp *sp, void *x * caused action scn. (The return value is used to make the state * transition decision in the state automaton.) */ -static int -sppp_ipcp_RCR(struct sppp *sp, struct lcp_header *h, int origlen) +static enum cp_rcr_type +sppp_ipcp_confreq(struct sppp *sp, struct lcp_header *h, int origlen, + uint8_t **msgbuf, size_t *buflen, size_t *msglen) { - u_char *buf, *r, *p, l, blen, type; + u_char *buf, *r, *p, l, blen; + enum cp_rcr_type type; struct ifnet *ifp = &sp->pp_if; int rlen, len, debug = ifp->if_flags & IFF_DEBUG; uint32_t hisaddr, desiredaddr; KASSERT(SPPP_WLOCKED(sp)); - if (origlen < sizeof(*h)) - return 0; - + type = CP_RCR_NONE; origlen -= sizeof(*h); - type = 0; + + if (origlen < 0) + return CP_RCR_DROP; /* * Make sure to allocate a buf that can at least hold a @@ -3343,7 +3381,7 @@ sppp_ipcp_RCR(struct sppp *sp, struct lc buf = kmem_intr_alloc(blen, KM_NOSLEEP); if (buf == NULL) - return 0; + return CP_RCR_DROP; /* pass 1: see if we can recognize them */ if (debug) @@ -3362,7 +3400,7 @@ sppp_ipcp_RCR(struct sppp *sp, struct lc /* XXX should we just RXJ? */ addlog("%s: malicious IPCP option received, dropping\n", ifp->if_xname); - rlen = -1; + type = CP_RCR_ERR; goto end; } if (debug) @@ -3404,7 +3442,7 @@ sppp_ipcp_RCR(struct sppp *sp, struct lc } if (rlen > 0) { - type = CONF_REJ; + type = CP_RCR_REJ; goto end; } @@ -3490,7 +3528,7 @@ sppp_ipcp_RCR(struct sppp *sp, struct lc } if (rlen > 0) { - type = CONF_NAK; + type = CP_RCR_NAK; } else { if ((sp->ipcp.flags & IPCP_HISADDR_SEEN) == 0) { /* @@ -3512,9 +3550,9 @@ sppp_ipcp_RCR(struct sppp *sp, struct lc rlen = 6; if (debug) addlog(" still need hisaddr"); - type = CONF_NAK; + type = CP_RCR_NAK; } else { - type = CONF_ACK; + type = CP_RCR_ACK; rlen = origlen; memcpy(r, h + 1, rlen); } @@ -3524,24 +3562,16 @@ end: if (debug) addlog("\n"); - if (rlen < 0) { - kmem_intr_free(buf, blen); - return -1; - } - - if (sp->scp[IDX_IPCP].rcr_buf != NULL) { - kmem_intr_free(sp->scp[IDX_IPCP].rcr_buf, - sp->scp[IDX_IPCP].rcr_blen); + if (type == CP_RCR_ERR || type == CP_RCR_DROP) { + if (buf != NULL) + kmem_intr_free(buf, blen); + } else { + *msgbuf = buf; + *buflen = blen; + *msglen = rlen; } - sp->scp[IDX_IPCP].rcr_type = type; - sp->scp[IDX_IPCP].rcr_buf = buf; - sp->scp[IDX_IPCP].rcr_blen = blen; - sp->scp[IDX_IPCP].rcr_rlen = rlen; - - if (type != CONF_ACK) - return 0; - return 1; + return type; } /* @@ -3549,7 +3579,7 @@ end: * negotiation. */ static void -sppp_ipcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len) +sppp_ipcp_confrej(struct sppp *sp, struct lcp_header *h, int len) { u_char *p, l; struct ifnet *ifp = &sp->pp_if; @@ -3607,7 +3637,7 @@ end: * negotiation. */ static void -sppp_ipcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len) +sppp_ipcp_confnak(struct sppp *sp, struct lcp_header *h, int len) { u_char *p, l; struct ifnet *ifp = &sp->pp_if; @@ -3822,25 +3852,26 @@ sppp_ipv6cp_open(struct sppp *sp, void * * caused action scn. (The return value is used to make the state * transition decision in the state automaton.) */ -static int -sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, int origlen) +static enum cp_rcr_type +sppp_ipv6cp_confreq(struct sppp *sp, struct lcp_header *h, int origlen, + uint8_t **msgbuf, size_t *buflen, size_t *msglen) { u_char *buf, *r, *p, l, blen; struct ifnet *ifp = &sp->pp_if; int rlen, len, debug = ifp->if_flags & IFF_DEBUG; struct in6_addr myaddr, desiredaddr, suggestaddr; + enum cp_rcr_type type; int ifidcount; - int type; int collision, nohisaddr; char ip6buf[INET6_ADDRSTRLEN]; KASSERT(SPPP_WLOCKED(sp)); - if (origlen < sizeof(*h)) - return 0; - + type = CP_RCR_NONE; origlen -= sizeof(*h); - type = 0; + + if (origlen < 0) + return CP_RCR_DROP; /* * Make sure to allocate a buf that can at least hold a @@ -3850,7 +3881,7 @@ sppp_ipv6cp_RCR(struct sppp *sp, struct buf = kmem_intr_alloc(blen, KM_NOSLEEP); if (buf == NULL) - return 0; + return CP_RCR_DROP; /* pass 1: see if we can recognize them */ if (debug) @@ -3870,7 +3901,7 @@ sppp_ipv6cp_RCR(struct sppp *sp, struct /* XXX just RXJ? */ addlog("%s: received malicious IPCPv6 option, " "dropping\n", ifp->if_xname); - rlen = -1; + type = CP_RCR_ERR; goto end; } if (debug) @@ -3913,7 +3944,7 @@ sppp_ipv6cp_RCR(struct sppp *sp, struct } if (rlen > 0) { - type = CONF_REJ; + type = CP_RCR_REJ; goto end; } @@ -3928,7 +3959,7 @@ sppp_ipv6cp_RCR(struct sppp *sp, struct p = (void *)(h + 1); r = buf; rlen = 0; - type = CONF_ACK; + type = CP_RCR_ACK; for (len = origlen; len > 1; len -= l, p += l) { l = p[1]; if (l == 0) @@ -3953,12 +3984,12 @@ sppp_ipv6cp_RCR(struct sppp *sp, struct if (!collision && !nohisaddr) { /* no collision, hisaddr known - Conf-Ack */ - type = CONF_ACK; + type = CP_RCR_ACK; if (debug) { addlog(" %s [%s]", IN6_PRINT(ip6buf, &desiredaddr), - sppp_cp_type_name(type)); + sppp_cp_type_name(CONF_ACK)); } continue; } @@ -3966,7 +3997,7 @@ sppp_ipv6cp_RCR(struct sppp *sp, struct memset(&suggestaddr, 0, sizeof(suggestaddr)); if (collision && nohisaddr) { /* collision, hisaddr unknown - Conf-Rej */ - type = CONF_REJ; + type = CP_RCR_REJ; memset(&p[2], 0, 8); } else { /* @@ -3974,13 +4005,15 @@ sppp_ipv6cp_RCR(struct sppp *sp, struct * - collision, hisaddr known * Conf-Nak, suggest hisaddr */ - type = CONF_NAK; + type = CP_RCR_NAK; sppp_suggest_ip6_addr(sp, &suggestaddr); memcpy(&p[2], &suggestaddr.s6_addr[8], 8); } - if (debug) + if (debug) { + int ctype = type == CP_RCR_REJ ? CONF_REJ : CONF_NAK; addlog(" %s [%s]", IN6_PRINT(ip6buf, &desiredaddr), - sppp_cp_type_name(type)); + sppp_cp_type_name(ctype)); + } break; } if (rlen + l > blen) { @@ -3995,19 +4028,22 @@ sppp_ipv6cp_RCR(struct sppp *sp, struct } if (rlen > 0) { - if (type != CONF_ACK) { + if (type != CP_RCR_ACK) { if (debug) { + int ctype ; + ctype = type == CP_RCR_REJ ? + CONF_REJ : CONF_NAK; addlog(" send %s suggest %s\n", - sppp_cp_type_name(type), + sppp_cp_type_name(ctype), IN6_PRINT(ip6buf, &suggestaddr)); } } #ifdef notdef - if (type == CONF_ACK) + if (type == CP_RCR_ACK) panic("IPv6CP RCR: CONF_ACK with non-zero rlen"); #endif } else { - if (type == CONF_ACK) { + if (type == CP_RCR_ACK) { rlen = origlen; memcpy(r, h + 1, rlen); } @@ -4016,24 +4052,16 @@ end: if (debug) addlog("\n"); - if (rlen < 0) { - kmem_intr_free(buf, blen); - return -1; - } - - if (sp->scp[IDX_IPV6CP].rcr_buf != NULL) { - kmem_intr_free(sp->scp[IDX_IPV6CP].rcr_buf, - sp->scp[IDX_IPV6CP].rcr_blen); + if (type == CP_RCR_ERR || type == CP_RCR_DROP) { + if (buf != NULL) + kmem_intr_free(buf, blen); + } else { + *msgbuf = buf; + *buflen = blen; + *msglen = rlen; } - sp->scp[IDX_IPV6CP].rcr_type = type; - sp->scp[IDX_IPV6CP].rcr_buf = buf; - sp->scp[IDX_IPV6CP].rcr_blen = blen; - sp->scp[IDX_IPV6CP].rcr_rlen = rlen; - - if (type != CONF_ACK) - return 0; - return 0; + return type; } /* @@ -4041,7 +4069,7 @@ end: * negotiation. */ static void -sppp_ipv6cp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len) +sppp_ipv6cp_confrej(struct sppp *sp, struct lcp_header *h, int len) { u_char *p, l; struct ifnet *ifp = &sp->pp_if; @@ -4098,7 +4126,7 @@ end: * negotiation. */ static void -sppp_ipv6cp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len) +sppp_ipv6cp_confnak(struct sppp *sp, struct lcp_header *h, int len) { u_char *p, l; struct ifnet *ifp = &sp->pp_if; @@ -4257,9 +4285,9 @@ sppp_ipv6cp_open(struct sppp *sp, void * KASSERT(SPPP_WLOCKED(sp)); } -static int -sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, - int len) +static enum cp_rcr_type +sppp_ipv6cp_confreq(struct sppp *sp, struct lcp_header *h, + int len, uint8_t **msgbuf, size_t *buflen, size_t *msglen) { KASSERT(SPPP_WLOCKED(sp)); @@ -4267,7 +4295,7 @@ sppp_ipv6cp_RCR(struct sppp *sp, struct } static void -sppp_ipv6cp_RCN_rej(struct sppp *sp, struct lcp_header *h, +sppp_ipv6cp_confrej(struct sppp *sp, struct lcp_header *h, int len) { @@ -4275,7 +4303,7 @@ sppp_ipv6cp_RCN_rej(struct sppp *sp, str } static void -sppp_ipv6cp_RCN_nak(struct sppp *sp, struct lcp_header *h, +sppp_ipv6cp_confnak(struct sppp *sp, struct lcp_header *h, int len) { @@ -4446,7 +4474,7 @@ sppp_chap_input(struct sppp *sp, struct * we are not authenticator for CHAP, * generate a dummy RCR+ event without CHAP_RESPONSE */ - sp->scp[IDX_CHAP].rcr_type = CONF_ACK; + sp->scp[IDX_CHAP].rcr_type = CP_RCR_ACK; sppp_wq_add(sp->wq_cp, &sp->scp[IDX_CHAP].work_rcr); } sppp_wq_add(sp->wq_cp, &sp->scp[IDX_CHAP].work_rca); @@ -4548,7 +4576,7 @@ sppp_chap_input(struct sppp *sp, struct addlog("\n"); /* generate RCR- event */ - sp->scp[IDX_CHAP].rcr_type = CONF_NAK; + sp->scp[IDX_CHAP].rcr_type = CP_RCR_NAK; sppp_wq_add(sp->wq_cp, &sp->scp[IDX_CHAP].work_rcr); break; } @@ -4575,14 +4603,14 @@ sppp_chap_input(struct sppp *sp, struct MD5Final(digest, &ctx); if (memcmp(digest, value, value_len) == 0) { - sp->scp[IDX_CHAP].rcr_type = CONF_ACK; + sp->scp[IDX_CHAP].rcr_type = CP_RCR_ACK; if (!ISSET(sppp_auth_role(&chap, sp), SPPP_AUTH_PEER) || sp->chap.rechallenging) { /* generate a dummy RCA event*/ sppp_wq_add(sp->wq_cp, &sp->scp[IDX_CHAP].work_rca); } } else { - sp->scp[IDX_CHAP].rcr_type = CONF_NAK; + sp->scp[IDX_CHAP].rcr_type = CP_RCR_NAK; } } else { if (debug) @@ -4592,7 +4620,7 @@ sppp_chap_input(struct sppp *sp, struct ifp->if_xname, value_len, sizeof(sp->chap.challenge)); - sp->scp[IDX_CHAP].rcr_type = CONF_NAK; + sp->scp[IDX_CHAP].rcr_type = CP_RCR_NAK; } sppp_wq_add(sp->wq_cp, &sp->scp[IDX_CHAP].work_rcr); @@ -4846,13 +4874,13 @@ sppp_pap_input(struct sppp *sp, struct m memcmp(name, sp->hisauth.name, name_len) == 0 && secret_len == sp->hisauth.secret_len && memcmp(secret, sp->hisauth.secret, secret_len) == 0) { - sp->scp[IDX_PAP].rcr_type = CONF_ACK; + sp->scp[IDX_PAP].rcr_type = CP_RCR_ACK; if (!ISSET(sppp_auth_role(&pap, sp), SPPP_AUTH_PEER)) { /* generate a dummy RCA event*/ sppp_wq_add(sp->wq_cp, &sp->scp[IDX_PAP].work_rca); } } else { - sp->scp[IDX_PAP].rcr_type = CONF_NAK; + sp->scp[IDX_PAP].rcr_type = CP_RCR_NAK; } sppp_wq_add(sp->wq_cp, &sp->scp[IDX_PAP].work_rcr); @@ -4889,7 +4917,7 @@ sppp_pap_input(struct sppp *sp, struct m /* we are not authenticator, generate a dummy RCR+ event */ if (!ISSET(sppp_auth_role(&pap, sp), SPPP_AUTH_SERV)) { - sp->scp[IDX_PAP].rcr_type = CONF_ACK; + sp->scp[IDX_PAP].rcr_type = CP_RCR_ACK; sppp_wq_add(sp->wq_cp, &sp->scp[IDX_PAP].work_rcr); } @@ -5182,7 +5210,7 @@ sppp_auth_sca_scn(const struct cp *cp, s rconfid = sp->scp[cp->protoidx].rconfid; - if (sp->scp[cp->protoidx].rcr_type == CONF_ACK) { + if (sp->scp[cp->protoidx].rcr_type == CP_RCR_ACK) { type = cp->proto == PPP_CHAP ? CHAP_SUCCESS : PAP_ACK; msg = succmsg; mlen = sizeof(succmsg) - 1; @@ -6263,12 +6291,12 @@ static void sppp_sca_scn(const struct cp *cp, struct sppp *sp) { STDDCL; - u_char rconfid, type, rlen; + u_char rconfid, rlen; + int type; void *buf; size_t blen; rconfid = sp->scp[cp->protoidx].rconfid; - type = sp->scp[cp->protoidx].rcr_type; buf = sp->scp[cp->protoidx].rcr_buf; rlen = sp->scp[cp->protoidx].rcr_rlen; blen = sp->scp[cp->protoidx].rcr_blen; @@ -6276,8 +6304,25 @@ sppp_sca_scn(const struct cp *cp, struct sp->scp[cp->protoidx].rcr_buf = NULL; sp->scp[cp->protoidx].rcr_blen = 0; + switch (sp->scp[cp->protoidx].rcr_type) { + case CP_RCR_ACK: + type = CONF_ACK; + break; + case CP_RCR_REJ: + type = CONF_REJ; + break; + case CP_RCR_NAK: + type = CONF_NAK; + break; + default: + type = -1; + break; + } + + sp->scp[cp->protoidx].rcr_type = CP_RCR_NONE; + if (buf != NULL) { - if (rlen > 0) { + if (rlen > 0 && type != -1) { if (debug) { log(LOG_DEBUG, "%s: send %s\n", ifp->if_xname, sppp_cp_type_name(type));