summaryrefslogtreecommitdiffstats
path: root/sys/net
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2001-07-31 07:27:01 +0000
committerume <ume@FreeBSD.org>2001-07-31 07:27:01 +0000
commitac97fb621f92fad9a5326b3199afc4d08d191de2 (patch)
treeda5db189870aed4ad7504fdcfdc8dd1076fb476b /sys/net
parent7ffebadcef03ef7d4c21bb2bacc7138cf1cce87a (diff)
downloadFreeBSD-src-ac97fb621f92fad9a5326b3199afc4d08d191de2.zip
FreeBSD-src-ac97fb621f92fad9a5326b3199afc4d08d191de2.tar.gz
If LCP proto-rej is received, drop the protocol mentioned by the message.
This is to be friendly with non-IPv6 peer (If the peer complains due to lack of IPv6CP, drop IPv6CP). This basically implements "RXJ+" state transition in the RFC. Obtained from: NetBSD
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if_spppsubr.c60
1 files changed, 59 insertions, 1 deletions
diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c
index 1fce3fe..1c1ab7f 100644
--- a/sys/net/if_spppsubr.c
+++ b/sys/net/if_spppsubr.c
@@ -1556,7 +1556,6 @@ sppp_cp_input(const struct cp *cp, struct sppp *sp, struct mbuf *m)
}
break;
case CODE_REJ:
- case PROTO_REJ:
/* XXX catastrophic rejects (RXJ-) aren't handled yet. */
log(LOG_INFO,
SPP_FMT "%s: ignoring RXJ (%s) for proto 0x%x, "
@@ -1583,6 +1582,65 @@ sppp_cp_input(const struct cp *cp, struct sppp *sp, struct mbuf *m)
++ifp->if_ierrors;
}
break;
+ case PROTO_REJ:
+ {
+ int catastrophic;
+ const struct cp *upper;
+ int i;
+ u_int16_t proto;
+
+ catastrophic = 0;
+ upper = NULL;
+ proto = ntohs(*((u_int16_t *)p));
+ for (i = 0; i < IDX_COUNT; i++) {
+ if (cps[i]->proto == proto) {
+ upper = cps[i];
+ break;
+ }
+ }
+ if (upper == NULL)
+ catastrophic++;
+
+ log(LOG_INFO,
+ SPP_FMT "%s: RXJ%c (%s) for proto 0x%x (%s/%s)\n",
+ SPP_ARGS(ifp), cp->name, catastrophic ? '-' : '+',
+ sppp_cp_type_name(h->type), proto,
+ upper ? upper->name : "unknown",
+ upper ? sppp_state_name(sp->state[upper->protoidx]) : "?");
+
+ /*
+ * if we got RXJ+ against conf-req, the peer does not implement
+ * this particular protocol type. terminate the protocol.
+ */
+ if (upper && !catastrophic) {
+ if (sp->state[upper->protoidx] == STATE_REQ_SENT) {
+ upper->Close(sp);
+ break;
+ }
+ }
+
+ /* XXX catastrophic rejects (RXJ-) aren't handled yet. */
+ switch (sp->state[cp->protoidx]) {
+ case STATE_CLOSED:
+ case STATE_STOPPED:
+ case STATE_REQ_SENT:
+ case STATE_ACK_SENT:
+ case STATE_CLOSING:
+ case STATE_STOPPING:
+ case STATE_OPENED:
+ break;
+ case STATE_ACK_RCVD:
+ sppp_cp_change_state(cp, sp, STATE_REQ_SENT);
+ break;
+ default:
+ printf(SPP_FMT "%s illegal %s in state %s\n",
+ SPP_ARGS(ifp), cp->name,
+ sppp_cp_type_name(h->type),
+ sppp_state_name(sp->state[cp->protoidx]));
+ ++ifp->if_ierrors;
+ }
+ break;
+ }
case DISC_REQ:
if (cp->proto != PPP_LCP)
goto illegal;
OpenPOWER on IntegriCloud