summaryrefslogtreecommitdiff
path: root/usr.sbin/ppp
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/ppp')
-rw-r--r--usr.sbin/ppp/ppp/atm.c3
-rw-r--r--usr.sbin/ppp/ppp/bundle.c23
-rw-r--r--usr.sbin/ppp/ppp/bundle.h4
-rw-r--r--usr.sbin/ppp/ppp/ccp.c138
-rw-r--r--usr.sbin/ppp/ppp/ccp.h21
-rw-r--r--usr.sbin/ppp/ppp/command.c132
-rw-r--r--usr.sbin/ppp/ppp/deflate.c14
-rw-r--r--usr.sbin/ppp/ppp/ether.c13
-rw-r--r--usr.sbin/ppp/ppp/exec.c3
-rw-r--r--usr.sbin/ppp/ppp/fsm.c22
-rw-r--r--usr.sbin/ppp/ppp/fsm.h6
-rw-r--r--usr.sbin/ppp/ppp/i4b.c3
-rw-r--r--usr.sbin/ppp/ppp/iface.c7
-rw-r--r--usr.sbin/ppp/ppp/iface.h3
-rw-r--r--usr.sbin/ppp/ppp/ip.c10
-rw-r--r--usr.sbin/ppp/ppp/lcp.c81
-rw-r--r--usr.sbin/ppp/ppp/lcp.h5
-rw-r--r--usr.sbin/ppp/ppp/mppe.c532
-rw-r--r--usr.sbin/ppp/ppp/physical.c8
-rw-r--r--usr.sbin/ppp/ppp/physical.h4
-rw-r--r--usr.sbin/ppp/ppp/ppp.878
-rw-r--r--usr.sbin/ppp/ppp/pred.c17
-rw-r--r--usr.sbin/ppp/ppp/route.c9
-rw-r--r--usr.sbin/ppp/ppp/tcp.c3
-rw-r--r--usr.sbin/ppp/ppp/tcpmss.c5
-rw-r--r--usr.sbin/ppp/ppp/tty.c3
-rw-r--r--usr.sbin/ppp/ppp/tun.c11
-rw-r--r--usr.sbin/ppp/ppp/udp.c3
28 files changed, 877 insertions, 284 deletions
diff --git a/usr.sbin/ppp/ppp/atm.c b/usr.sbin/ppp/ppp/atm.c
index 902c5c85f3d..d234786459e 100644
--- a/usr.sbin/ppp/ppp/atm.c
+++ b/usr.sbin/ppp/ppp/atm.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: atm.c,v 1.3 2001/01/29 08:47:43 brian Exp $
+ * $OpenBSD: atm.c,v 1.4 2001/06/19 10:24:49 brian Exp $
*/
#include <sys/types.h>
@@ -122,6 +122,7 @@ atm_device2iov(struct device *d, struct iovec *iov, int *niov,
static const struct device baseatmdevice = {
ATM_DEVICE,
"atm",
+ 0,
{ CD_NOTREQUIRED, 0 },
NULL,
NULL,
diff --git a/usr.sbin/ppp/ppp/bundle.c b/usr.sbin/ppp/ppp/bundle.c
index fcb713b3df4..c26d9cf0f0d 100644
--- a/usr.sbin/ppp/ppp/bundle.c
+++ b/usr.sbin/ppp/ppp/bundle.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: bundle.c,v 1.56 2001/04/05 02:24:04 brian Exp $
+ * $OpenBSD: bundle.c,v 1.57 2001/06/19 10:24:49 brian Exp $
*/
#include <sys/param.h>
@@ -802,7 +802,6 @@ bundle_Create(const char *prefix, int type, int unit)
log_Printf(LogPHASE, "Using interface: %s\n", ifname);
bundle.bandwidth = 0;
- bundle.mtu = 1500;
bundle.routing_seq = 0;
bundle.phase = PHASE_DEAD;
bundle.CleaningUp = 0;
@@ -821,7 +820,6 @@ bundle_Create(const char *prefix, int type, int unit)
bundle.cfg.opt = OPT_SROUTES | OPT_IDCHECK | OPT_LOOPBACK | OPT_TCPMSSFIXUP |
OPT_THROUGHPUT | OPT_UTMP;
*bundle.cfg.label = '\0';
- bundle.cfg.mtu = DEF_MTU;
bundle.cfg.ifqueue = DEF_IFQUEUE;
bundle.cfg.choked.timeout = CHOKED_TIMEOUT;
bundle.phys_type.all = type;
@@ -1096,11 +1094,6 @@ bundle_ShowStatus(struct cmdargs const *arg)
prompt_Printf(arg->prompt, "\n");
} else
prompt_Printf(arg->prompt, "disabled\n");
- prompt_Printf(arg->prompt, " MTU: ");
- if (arg->bundle->cfg.mtu)
- prompt_Printf(arg->prompt, "%d\n", arg->bundle->cfg.mtu);
- else
- prompt_Printf(arg->prompt, "unspecified\n");
prompt_Printf(arg->prompt, " sendpipe: ");
if (arg->bundle->ncp.ipcp.cfg.sendpipe > 0)
@@ -1826,7 +1819,7 @@ bundle_CalculateBandwidth(struct bundle *bundle)
int sp;
bundle->bandwidth = 0;
- bundle->mtu = 0;
+ bundle->iface->mtu = 0;
for (dl = bundle->links; dl; dl = dl->next)
if (dl->state == DATALINK_OPEN) {
if ((sp = dl->mp.bandwidth) == 0 &&
@@ -1836,7 +1829,7 @@ bundle_CalculateBandwidth(struct bundle *bundle)
else
bundle->bandwidth += sp;
if (!bundle->ncp.mp.active) {
- bundle->mtu = dl->physical->link.lcp.his_mru;
+ bundle->iface->mtu = dl->physical->link.lcp.his_mru;
break;
}
}
@@ -1845,16 +1838,16 @@ bundle_CalculateBandwidth(struct bundle *bundle)
bundle->bandwidth = 115200; /* Shrug */
if (bundle->ncp.mp.active)
- bundle->mtu = bundle->ncp.mp.peer_mrru;
- else if (!bundle->mtu)
- bundle->mtu = 1500;
+ bundle->iface->mtu = bundle->ncp.mp.peer_mrru;
+ else if (!bundle->iface->mtu)
+ bundle->iface->mtu = DEF_MRU;
#ifndef NORADIUS
if (bundle->radius.valid && bundle->radius.mtu &&
- bundle->radius.mtu < bundle->mtu) {
+ bundle->radius.mtu < bundle->iface->mtu) {
log_Printf(LogLCP, "Reducing MTU to radius value %lu\n",
bundle->radius.mtu);
- bundle->mtu = bundle->radius.mtu;
+ bundle->iface->mtu = bundle->radius.mtu;
}
#endif
diff --git a/usr.sbin/ppp/ppp/bundle.h b/usr.sbin/ppp/ppp/bundle.h
index f5f6bb64ab1..ed70c58ff31 100644
--- a/usr.sbin/ppp/ppp/bundle.h
+++ b/usr.sbin/ppp/ppp/bundle.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: bundle.h,v 1.20 2001/04/05 02:24:05 brian Exp $
+ * $OpenBSD: bundle.h,v 1.21 2001/06/19 10:24:50 brian Exp $
*/
#define PHASE_DEAD 0 /* Link is dead */
@@ -73,7 +73,6 @@ struct bundle {
} dev;
u_long bandwidth; /* struct tuninfo speed */
- int mtu; /* struct tuninfo MTU */
struct iface *iface; /* Interface information */
int routing_seq; /* The current routing sequence number */
@@ -103,7 +102,6 @@ struct bundle {
} auth;
unsigned opt; /* Uses OPT_ bits from above */
char label[50]; /* last thing `load'ed */
- u_short mtu; /* Required interface MTU */
u_short ifqueue; /* Interface queue size */
struct {
diff --git a/usr.sbin/ppp/ppp/ccp.c b/usr.sbin/ppp/ppp/ccp.c
index 35bbb9dc7ab..db3eceb3b58 100644
--- a/usr.sbin/ppp/ppp/ccp.c
+++ b/usr.sbin/ppp/ppp/ccp.c
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: ccp.c,v 1.19 2001/06/13 21:33:40 brian Exp $
+ * $OpenBSD: ccp.c,v 1.20 2001/06/19 10:24:50 brian Exp $
*/
#include <sys/param.h>
@@ -82,7 +82,7 @@ static void CcpLayerFinish(struct fsm *);
static int CcpLayerUp(struct fsm *);
static void CcpLayerDown(struct fsm *);
static void CcpInitRestartCounter(struct fsm *, int);
-static void CcpRecvResetReq(struct fsm *);
+static int CcpRecvResetReq(struct fsm *);
static void CcpRecvResetAck(struct fsm *, u_char);
static struct fsm_callbacks ccp_Callbacks = {
@@ -150,8 +150,10 @@ static const struct ccp_algorithm * const algorithm[] = {
int
ccp_ReportStatus(struct cmdargs const *arg)
{
+ struct ccp_opt **o;
struct link *l;
struct ccp *ccp;
+ int f;
l = command_ChooseLink(arg);
ccp = &l->ccp;
@@ -166,6 +168,19 @@ ccp_ReportStatus(struct cmdargs const *arg)
ccp->compin, ccp->uncompin);
}
+ if (ccp->in.algorithm != -1)
+ prompt_Printf(arg->prompt, "\n Input Options: %s\n",
+ (*algorithm[ccp->in.algorithm]->Disp)(&ccp->in.opt));
+
+ if (ccp->out.algorithm != -1) {
+ o = &ccp->out.opt;
+ for (f = 0; f < ccp->out.algorithm; f++)
+ if (IsEnabled(ccp->cfg.neg[algorithm[f]->Neg]))
+ o = &(*o)->next;
+ prompt_Printf(arg->prompt, " Output Options: %s\n",
+ (*algorithm[ccp->out.algorithm]->Disp)(&(*o)->val));
+ }
+
prompt_Printf(arg->prompt, "\n Defaults: ");
prompt_Printf(arg->prompt, "FSM retry = %us, max %u Config"
" REQ%s, %u Term REQ%s\n", ccp->cfg.fsm.timeout,
@@ -174,16 +189,36 @@ ccp_ReportStatus(struct cmdargs const *arg)
prompt_Printf(arg->prompt, " deflate windows: ");
prompt_Printf(arg->prompt, "incoming = %d, ", ccp->cfg.deflate.in.winsize);
prompt_Printf(arg->prompt, "outgoing = %d\n", ccp->cfg.deflate.out.winsize);
- prompt_Printf(arg->prompt, " DEFLATE: %s\n",
+#ifdef HAVE_DES
+ prompt_Printf(arg->prompt, " MPPE: ");
+ if (ccp->cfg.mppe.keybits)
+ prompt_Printf(arg->prompt, "%d bits, ", ccp->cfg.mppe.keybits);
+ else
+ prompt_Printf(arg->prompt, "any bits, ");
+ switch (ccp->cfg.mppe.state) {
+ case MPPE_STATEFUL:
+ prompt_Printf(arg->prompt, "statefull");
+ break;
+ case MPPE_STATELESS:
+ prompt_Printf(arg->prompt, "stateless");
+ break;
+ case MPPE_ANYSTATE:
+ prompt_Printf(arg->prompt, "any state");
+ break;
+ }
+ prompt_Printf(arg->prompt, "%s\n",
+ ccp->cfg.mppe.required ? ", required" : "");
+#endif
+
+ prompt_Printf(arg->prompt, "\n DEFLATE: %s\n",
command_ShowNegval(ccp->cfg.neg[CCP_NEG_DEFLATE]));
prompt_Printf(arg->prompt, " PREDICTOR1: %s\n",
command_ShowNegval(ccp->cfg.neg[CCP_NEG_PRED1]));
prompt_Printf(arg->prompt, " DEFLATE24: %s\n",
command_ShowNegval(ccp->cfg.neg[CCP_NEG_DEFLATE24]));
#ifdef HAVE_DES
- prompt_Printf(arg->prompt, " MPPE: %s",
+ prompt_Printf(arg->prompt, " MPPE: %s\n",
command_ShowNegval(ccp->cfg.neg[CCP_NEG_MPPE]));
- prompt_Printf(arg->prompt, " (Key Size = %d-bits)\n", ccp->cfg.mppe.keybits);
#endif
return 0;
}
@@ -215,7 +250,9 @@ ccp_Init(struct ccp *ccp, struct bundle *bundle, struct link *l,
ccp->cfg.neg[CCP_NEG_PRED1] = NEG_ENABLED|NEG_ACCEPTED;
ccp->cfg.neg[CCP_NEG_DEFLATE24] = 0;
#ifdef HAVE_DES
- ccp->cfg.mppe.keybits = 128;
+ ccp->cfg.mppe.keybits = 0;
+ ccp->cfg.mppe.state = MPPE_ANYSTATE;
+ ccp->cfg.mppe.required = 0;
ccp->cfg.neg[CCP_NEG_MPPE] = NEG_ENABLED|NEG_ACCEPTED;
#endif
@@ -238,6 +275,30 @@ ccp_Setup(struct ccp *ccp)
ccp->uncompin = ccp->compin = 0;
}
+/*
+ * Is ccp *REQUIRED* ?
+ * We ask each of the configured ccp protocols if they're required and
+ * return TRUE if they are.
+ *
+ * It's not possible for the peer to reject a required ccp protocol
+ * without our state machine bringing the supporting lcp layer down.
+ *
+ * If ccp is required but not open, the NCP layer should not push
+ * any data into the link.
+ */
+int
+ccp_Required(struct ccp *ccp)
+{
+ int f;
+
+ for (f = 0; f < NALGORITHMS; f++)
+ if (IsEnabled(ccp->cfg.neg[algorithm[f]->Neg]) &&
+ (*algorithm[f]->Required)(&ccp->fsm))
+ return 1;
+
+ return 0;
+}
+
static void
CcpInitRestartCounter(struct fsm *fp, int what)
{
@@ -332,13 +393,14 @@ CcpSendTerminateAck(struct fsm *fp, u_char id)
fsm_Output(fp, CODE_TERMACK, id, NULL, 0, MB_CCPOUT);
}
-static void
+static int
CcpRecvResetReq(struct fsm *fp)
{
/* Got a reset REQ, reset outgoing dictionary */
struct ccp *ccp = fsm2ccp(fp);
- if (ccp->out.state != NULL)
- (*algorithm[ccp->out.algorithm]->o.Reset)(ccp->out.state);
+ if (ccp->out.state == NULL)
+ return 1;
+ return (*algorithm[ccp->out.algorithm]->o.Reset)(ccp->out.state);
}
static void
@@ -397,6 +459,12 @@ CcpLayerFinish(struct fsm *fp)
free(ccp->out.opt);
ccp->out.opt = next;
}
+
+ if (ccp_Required(ccp)) {
+ if (fp->link->lcp.fsm.state == ST_OPENED)
+ log_Printf(LogLCP, "%s: Closing due to CCP completion\n", fp->link->name);
+ fsm_Close(&fp->link->lcp.fsm);
+ }
}
/* Called when CCP has reached the OPEN state */
@@ -531,17 +599,28 @@ CcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
" option\n", fp->link->name);
else {
memcpy(&o->val, cp, length);
- if ((*algorithm[f]->o.Set)(&o->val) == MODE_ACK)
+ if ((*algorithm[f]->o.Set)(&o->val, &ccp->cfg) == MODE_ACK)
ccp->my_proto = algorithm[f]->id;
else {
ccp->his_reject |= (1 << type);
ccp->my_proto = -1;
+ if (algorithm[f]->Required(fp)) {
+ log_Printf(LogWARN, "%s: Cannot understand peers (required)"
+ " %s negotiation\n", fp->link->name,
+ protoname(algorithm[f]->id));
+ fsm_Close(&fp->link->lcp.fsm);
+ }
}
}
break;
case MODE_REJ:
ccp->his_reject |= (1 << type);
ccp->my_proto = -1;
+ if (algorithm[f]->Required(fp)) {
+ log_Printf(LogWARN, "%s: Peer rejected (required) %s negotiation\n",
+ fp->link->name, protoname(algorithm[f]->id));
+ fsm_Close(&fp->link->lcp.fsm);
+ }
break;
}
}
@@ -618,17 +697,26 @@ static struct mbuf *
ccp_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp,
int pri, u_short *proto)
{
- if (PROTO_COMPRESSIBLE(*proto) && l->ccp.fsm.state == ST_OPENED &&
- l->ccp.out.state != NULL) {
- bp = (*algorithm[l->ccp.out.algorithm]->o.Write)
- (l->ccp.out.state, &l->ccp, l, pri, proto, bp);
- switch (*proto) {
- case PROTO_ICOMPD:
- m_settype(bp, MB_ICOMPDOUT);
- break;
- case PROTO_COMPD:
- m_settype(bp, MB_COMPDOUT);
- break;
+ if (PROTO_COMPRESSIBLE(*proto)) {
+ if (l->ccp.fsm.state != ST_OPENED) {
+ if (ccp_Required(&l->ccp)) {
+ /* The NCP layer shouldn't have let this happen ! */
+ log_Printf(LogERROR, "%s: Unexpected attempt to use an unopened and"
+ " required CCP layer\n", l->name);
+ m_freem(bp);
+ bp = NULL;
+ }
+ } else if (l->ccp.out.state != NULL) {
+ bp = (*algorithm[l->ccp.out.algorithm]->o.Write)
+ (l->ccp.out.state, &l->ccp, l, pri, proto, bp);
+ switch (*proto) {
+ case PROTO_ICOMPD:
+ m_settype(bp, MB_ICOMPDOUT);
+ break;
+ case PROTO_COMPD:
+ m_settype(bp, MB_COMPDOUT);
+ break;
+ }
}
}
@@ -706,9 +794,15 @@ ccp_SetOpenMode(struct ccp *ccp)
}
int
-ccp_IsUsable(struct fsm *fp)
+ccp_DefaultUsable(struct fsm *fp)
{
return 1;
}
+int
+ccp_DefaultRequired(struct fsm *fp)
+{
+ return 0;
+}
+
struct layer ccplayer = { LAYER_CCP, "ccp", ccp_LayerPush, ccp_LayerPull };
diff --git a/usr.sbin/ppp/ppp/ccp.h b/usr.sbin/ppp/ppp/ccp.h
index 56c15f5d631..49918eb703d 100644
--- a/usr.sbin/ppp/ppp/ccp.h
+++ b/usr.sbin/ppp/ppp/ccp.h
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: ccp.h,v 1.9 2001/06/13 21:33:40 brian Exp $
+ * $OpenBSD: ccp.h,v 1.10 2001/06/19 10:24:50 brian Exp $
*/
#define CCP_MAXCODE CODE_RESETACK
@@ -54,6 +54,14 @@
#define CCP_NEG_TOTAL 3
#endif
+#ifdef HAVE_DES
+enum mppe_negstate {
+ MPPE_ANYSTATE,
+ MPPE_STATELESS,
+ MPPE_STATEFUL
+};
+#endif
+
struct mbuf;
struct link;
@@ -66,6 +74,8 @@ struct ccp_config {
#ifdef HAVE_DES
struct {
int keybits;
+ enum mppe_negstate state;
+ unsigned required : 1;
} mppe;
#endif
struct fsm_retry fsm; /* How often/frequently to resend requests */
@@ -115,6 +125,7 @@ struct ccp_algorithm {
int Neg; /* ccp_config neg array item */
const char *(*Disp)(struct lcp_opt *); /* Use result immediately ! */
int (*Usable)(struct fsm *); /* Ok to negotiate ? */
+ int (*Required)(struct fsm *); /* Must negotiate ? */
struct {
int (*Set)(struct lcp_opt *, const struct ccp_config *);
void *(*Init)(struct lcp_opt *);
@@ -125,10 +136,10 @@ struct ccp_algorithm {
} i;
struct {
void (*OptInit)(struct lcp_opt *, const struct ccp_config *);
- int (*Set)(struct lcp_opt *);
+ int (*Set)(struct lcp_opt *, const struct ccp_config *);
void *(*Init)(struct lcp_opt *);
void (*Term)(void *);
- void (*Reset)(void *);
+ int (*Reset)(void *);
struct mbuf *(*Write)(void *, struct ccp *, struct link *, int, u_short *,
struct mbuf *);
} o;
@@ -137,6 +148,7 @@ struct ccp_algorithm {
extern void ccp_Init(struct ccp *, struct bundle *, struct link *,
const struct fsm_parent *);
extern void ccp_Setup(struct ccp *);
+extern int ccp_Required(struct ccp *);
extern void ccp_SendResetReq(struct fsm *);
extern struct mbuf *ccp_Input(struct bundle *, struct link *, struct mbuf *);
@@ -144,6 +156,7 @@ extern int ccp_ReportStatus(struct cmdargs const *);
extern u_short ccp_Proto(struct ccp *);
extern void ccp_SetupCallbacks(struct ccp *);
extern int ccp_SetOpenMode(struct ccp *);
-extern int ccp_IsUsable(struct fsm *);
+extern int ccp_DefaultUsable(struct fsm *);
+extern int ccp_DefaultRequired(struct fsm *);
extern struct layer ccplayer;
diff --git a/usr.sbin/ppp/ppp/command.c b/usr.sbin/ppp/ppp/command.c
index eabf36e0167..2dc0d17c6df 100644
--- a/usr.sbin/ppp/ppp/command.c
+++ b/usr.sbin/ppp/ppp/command.c
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: command.c,v 1.59 2001/06/13 21:33:40 brian Exp $
+ * $OpenBSD: command.c,v 1.60 2001/06/19 10:24:51 brian Exp $
*/
#include <sys/param.h>
@@ -135,7 +135,7 @@
#define VAR_URGENTPORTS 33
#define VAR_LOGOUT 34
#define VAR_IFQUEUE 35
-#define VAR_KEYBITS 36
+#define VAR_MPPE 36
/* ``accept|deny|disable|enable'' masks */
#define NEG_HISMASK (1)
@@ -159,7 +159,7 @@
#define NEG_MPPE 54
#define NEG_CHAP81 55
-const char Version[] = "2.3.1";
+const char Version[] = "2.3.2";
static int ShowCommand(struct cmdargs const *);
static int TerminalCommand(struct cmdargs const *);
@@ -1489,6 +1489,7 @@ SetVariable(struct cmdargs const *arg)
{
long long_val, param = (long)arg->cmd->args;
int mode, dummyint, f, first;
+ u_short *change;
const char *argp;
struct datalink *cx = arg->cx; /* LOCAL_CX uses this */
const char *err = NULL;
@@ -1609,20 +1610,43 @@ SetVariable(struct cmdargs const *arg)
break;
#ifdef HAVE_DES
- case VAR_KEYBITS:
- if (arg->argc > arg->argn) {
- l->ccp.cfg.mppe.keybits = atoi(arg->argv[arg->argn]);
- if (l->ccp.cfg.mppe.keybits != 40 &&
- l->ccp.cfg.mppe.keybits != 56 &&
- l->ccp.cfg.mppe.keybits != 128 ) {
- log_Printf(LogWARN, "%d: Invalid bits number\n",
- l->ccp.cfg.mppe.keybits);
- l->ccp.cfg.mppe.keybits = 40;
+ case VAR_MPPE:
+ if (arg->argc > arg->argn + 2)
+ return -1;
+
+ if (arg->argc == arg->argn) {
+ l->ccp.cfg.mppe.keybits = 0;
+ l->ccp.cfg.mppe.state = MPPE_ANYSTATE;
+ l->ccp.cfg.mppe.required = 0;
+ break;
+ }
+
+ if (!strcmp(argp, "*"))
+ long_val = 0;
+ else {
+ long_val = atol(argp);
+ if (long_val != 40 && long_val != 56 && long_val != 128) {
+ log_Printf(LogWARN, "%s: Invalid bits value\n", argp);
+ return -1;
}
- } else {
- err = "No bits number pecified\n";
- log_Printf(LogWARN, err);
}
+
+ if (arg->argc == arg->argn + 2) {
+ if (!strcmp(arg->argv[arg->argn + 1], "*"))
+ l->ccp.cfg.mppe.state = MPPE_ANYSTATE;
+ else if (!strcasecmp(arg->argv[arg->argn + 1], "stateless"))
+ l->ccp.cfg.mppe.state = MPPE_STATELESS;
+ else if (!strcasecmp(arg->argv[arg->argn + 1], "statefull"))
+ l->ccp.cfg.mppe.state = MPPE_STATEFUL;
+ else {
+ log_Printf(LogWARN, "%s: Invalid state value\n",
+ arg->argv[arg->argn + 1]);
+ return -1;
+ }
+ } else
+ l->ccp.cfg.mppe.state = MPPE_ANYSTATE;
+ l->ccp.cfg.mppe.keybits = long_val;
+ l->ccp.cfg.mppe.required = 1;
break;
#endif
@@ -1678,9 +1702,36 @@ SetVariable(struct cmdargs const *arg)
break;
case VAR_MRU:
- long_val = atol(argp);
+ switch(arg->argc - arg->argn) {
+ case 1:
+ if (argp[strspn(argp, "0123456789")] != '\0')
+ return -1;
+ case 0:
+ long_val = atol(argp);
+ change = &l->lcp.cfg.mru;
+ if (long_val > l->lcp.cfg.max_mru) {
+ log_Printf(LogWARN, "MRU %ld: too large - max set to %d\n", long_val,
+ l->lcp.cfg.max_mru);
+ return 1;
+ }
+ break;
+ case 2:
+ if (strcasecmp(argp, "max") && strcasecmp(argp, "maximum"))
+ return -1;
+ long_val = atol(arg->argv[arg->argn + 1]);
+ change = &l->lcp.cfg.max_mru;
+ if (long_val > MAX_MRU) {
+ log_Printf(LogWARN, "MRU %ld: too large - maximum is %d\n", long_val,
+ MAX_MRU);
+ return 1;
+ }
+ break;
+ default:
+ return -1;
+ }
+
if (long_val == 0)
- l->lcp.cfg.mru = DEF_MRU;
+ *change = DEF_MRU;
else if (long_val < MIN_MRU) {
log_Printf(LogWARN, "MRU %ld: too small - min %d\n", long_val, MIN_MRU);
return 1;
@@ -1688,11 +1739,40 @@ SetVariable(struct cmdargs const *arg)
log_Printf(LogWARN, "MRU %ld: too big - max %d\n", long_val, MAX_MRU);
return 1;
} else
- l->lcp.cfg.mru = long_val;
+ *change = long_val;
+ if (l->lcp.cfg.mru > *change)
+ l->lcp.cfg.mru = *change;
break;
case VAR_MTU:
- long_val = atol(argp);
+ switch(arg->argc - arg->argn) {
+ case 1:
+ if (argp[strspn(argp, "0123456789")] != '\0')
+ return -1;
+ case 0:
+ long_val = atol(argp);
+ change = &l->lcp.cfg.mtu;
+ if (long_val > l->lcp.cfg.max_mtu) {
+ log_Printf(LogWARN, "MTU %ld: too large - max set to %d\n", long_val,
+ l->lcp.cfg.max_mtu);
+ return 1;
+ }
+ break;
+ case 2:
+ if (strcasecmp(argp, "max") && strcasecmp(argp, "maximum"))
+ return -1;
+ long_val = atol(arg->argv[arg->argn + 1]);
+ change = &l->lcp.cfg.max_mtu;
+ if (long_val > MAX_MTU) {
+ log_Printf(LogWARN, "MTU %ld: too large - maximum is %d\n", long_val,
+ MAX_MTU);
+ return 1;
+ }
+ break;
+ default:
+ return -1;
+ }
+
if (long_val && long_val < MIN_MTU) {
log_Printf(LogWARN, "MTU %ld: too small - min %d\n", long_val, MIN_MTU);
return 1;
@@ -1700,7 +1780,9 @@ SetVariable(struct cmdargs const *arg)
log_Printf(LogWARN, "MTU %ld: too big - max %d\n", long_val, MAX_MTU);
return 1;
} else
- arg->bundle->cfg.mtu = long_val;
+ *change = long_val;
+ if (l->lcp.cfg.mtu > *change)
+ l->lcp.cfg.mtu = *change;
break;
case VAR_OPENMODE:
@@ -2022,8 +2104,8 @@ static struct cmdtab const SetCommands[] = {
(const void *) VAR_WINSIZE},
#ifdef HAVE_DES
{"mppe", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX_OPT,
- "MPPE key size", "set mppe {40|56|128}",
- (const void *) VAR_KEYBITS},
+ "MPPE key size and state", "set mppe [40|56|128|* [statefull|stateless|*]]",
+ (const void *) VAR_MPPE},
#endif
{"device", "line", SetVariable, LOCAL_AUTH | LOCAL_CX,
"physical device name", "set device|line device-name[,device-name]",
@@ -2064,9 +2146,9 @@ static struct cmdtab const SetCommands[] = {
{"mrru", NULL, SetVariable, LOCAL_AUTH, "MRRU value",
"set mrru value", (const void *)VAR_MRRU},
{"mru", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX_OPT,
- "MRU value", "set mru value", (const void *)VAR_MRU},
- {"mtu", NULL, SetVariable, LOCAL_AUTH,
- "interface MTU value", "set mtu value", (const void *)VAR_MTU},
+ "MRU value", "set mru [max[imum]] [value]", (const void *)VAR_MRU},
+ {"mtu", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX,
+ "interface MTU value", "set mtu [max[imum]] [value]", (const void *)VAR_MTU},
{"nbns", NULL, SetVariable, LOCAL_AUTH, "NetBIOS Name Server",
"set nbns pri-addr [sec-addr]", (const void *)VAR_NBNS},
{"openmode", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX, "open mode",
diff --git a/usr.sbin/ppp/ppp/deflate.c b/usr.sbin/ppp/ppp/deflate.c
index 2181b1fb9ec..0e9281db0f9 100644
--- a/usr.sbin/ppp/ppp/deflate.c
+++ b/usr.sbin/ppp/ppp/deflate.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: deflate.c,v 1.11 2001/02/04 22:53:13 brian Exp $
+ * $OpenBSD: deflate.c,v 1.12 2001/06/19 10:24:51 brian Exp $
*/
#include <sys/types.h>
@@ -57,7 +57,7 @@ static u_char EMPTY_BLOCK[4] = { 0x00, 0x00, 0xff, 0xff };
#define DEFLATE_CHUNK_LEN (1536 - sizeof(struct mbuf))
-static void
+static int
DeflateResetOutput(void *v)
{
struct deflate_state *state = (struct deflate_state *)v;
@@ -66,6 +66,8 @@ DeflateResetOutput(void *v)
state->uncomp_rec = 0;
deflateReset(&state->cx);
log_Printf(LogCCP, "Deflate: Output channel reset\n");
+
+ return 1; /* Ask FSM to ACK */
}
static struct mbuf *
@@ -451,7 +453,7 @@ DeflateInitOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg)
}
static int
-DeflateSetOptsOutput(struct lcp_opt *o)
+DeflateSetOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg)
{
if (o->len != 4 || (o->data[0] & 15) != 8 || o->data[1] != '\0')
return MODE_REJ;
@@ -554,7 +556,8 @@ const struct ccp_algorithm PppdDeflateAlgorithm = {
TY_PPPD_DEFLATE, /* Older versions of pppd expected this ``type'' */
CCP_NEG_DEFLATE24,
DeflateDispOpts,
- ccp_IsUsable,
+ ccp_DefaultUsable,
+ ccp_DefaultRequired,
{
DeflateSetOptsInput,
DeflateInitInput,
@@ -577,7 +580,8 @@ const struct ccp_algorithm DeflateAlgorithm = {
TY_DEFLATE, /* rfc 1979 */
CCP_NEG_DEFLATE,
DeflateDispOpts,
- ccp_IsUsable,
+ ccp_DefaultUsable,
+ ccp_DefaultRequired,
{
DeflateSetOptsInput,
DeflateInitInput,
diff --git a/usr.sbin/ppp/ppp/ether.c b/usr.sbin/ppp/ppp/ether.c
index 79896af287e..cbc07f39df2 100644
--- a/usr.sbin/ppp/ppp/ether.c
+++ b/usr.sbin/ppp/ppp/ether.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: ether.c,v 1.10 2001/06/04 16:09:28 brian Exp $
+ * $OpenBSD: ether.c,v 1.11 2001/06/19 10:24:52 brian Exp $
*/
#include <sys/param.h>
@@ -285,6 +285,7 @@ ether_AwaitCarrier(struct physical *p)
static const struct device baseetherdevice = {
ETHER_DEVICE,
"ether",
+ 1492,
{ CD_REQUIRED, DEF_ETHERCDDELAY },
ether_AwaitCarrier,
ether_RemoveFromSet,
@@ -675,16 +676,6 @@ ether_Create(struct physical *p)
if (dev) {
physical_SetupStack(p, dev->dev.name, PHYSICAL_FORCE_SYNCNOACF);
- /* Moan about (and fix) invalid LCP configurations */
- if (p->link.lcp.cfg.mru > 1492) {
- log_Printf(LogWARN, "%s: Reducing MRU to 1492\n", p->link.name);
- p->link.lcp.cfg.mru = 1492;
- }
- if (p->dl->bundle->cfg.mtu > 1492) {
- log_Printf(LogWARN, "%s: Reducing MTU to 1492\n", p->link.name);
- p->dl->bundle->cfg.mtu = 1492;
- }
-
if (path != NULL) {
/* Mark the interface as UP if it's not already */
diff --git a/usr.sbin/ppp/ppp/exec.c b/usr.sbin/ppp/ppp/exec.c
index 187999e2b1d..ff681b4ce40 100644
--- a/usr.sbin/ppp/ppp/exec.c
+++ b/usr.sbin/ppp/ppp/exec.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: exec.c,v 1.15 2000/08/18 00:02:11 brian Exp $
+ * $OpenBSD: exec.c,v 1.16 2001/06/19 10:24:52 brian Exp $
*/
#include <sys/param.h>
@@ -68,6 +68,7 @@
static struct device execdevice = {
EXEC_DEVICE,
"exec",
+ 0,
{ CD_NOTREQUIRED, 0 },
NULL,
NULL,
diff --git a/usr.sbin/ppp/ppp/fsm.c b/usr.sbin/ppp/ppp/fsm.c
index 39444667ba2..687e1753ff8 100644
--- a/usr.sbin/ppp/ppp/fsm.c
+++ b/usr.sbin/ppp/ppp/fsm.c
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: fsm.c,v 1.17 2001/06/13 21:33:41 brian Exp $
+ * $OpenBSD: fsm.c,v 1.18 2001/06/19 10:24:52 brian Exp $
*/
#include <sys/param.h>
@@ -978,14 +978,15 @@ FsmRecvTimeRemain(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
static void
FsmRecvResetReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
{
- (*fp->fn->RecvResetReq)(fp);
- /*
- * All sendable compressed packets are queued in the first (lowest
- * priority) modem output queue.... dump 'em to the priority queue
- * so that they arrive at the peer before our ResetAck.
- */
- link_SequenceQueue(fp->link);
- fsm_Output(fp, CODE_RESETACK, lhp->id, NULL, 0, MB_CCPOUT);
+ if ((*fp->fn->RecvResetReq)(fp)) {
+ /*
+ * All sendable compressed packets are queued in the first (lowest
+ * priority) modem output queue.... dump 'em to the priority queue
+ * so that they arrive at the peer before our ResetAck.
+ */
+ link_SequenceQueue(fp->link);
+ fsm_Output(fp, CODE_RESETACK, lhp->id, NULL, 0, MB_CCPOUT);
+ }
m_freem(bp);
}
@@ -1050,11 +1051,12 @@ fsm_Input(struct fsm *fp, struct mbuf *bp)
(*codep->recv)(fp, &lh, bp);
}
-void
+int
fsm_NullRecvResetReq(struct fsm *fp)
{
log_Printf(fp->LogLevel, "%s: Oops - received unexpected reset req\n",
fp->link->name);
+ return 1;
}
void
diff --git a/usr.sbin/ppp/ppp/fsm.h b/usr.sbin/ppp/ppp/fsm.h
index f9ee7d9f046..200dc15d1dd 100644
--- a/usr.sbin/ppp/ppp/fsm.h
+++ b/usr.sbin/ppp/ppp/fsm.h
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: fsm.h,v 1.7 2001/06/13 21:33:41 brian Exp $
+ * $OpenBSD: fsm.h,v 1.8 2001/06/19 10:24:53 brian Exp $
*/
/*
@@ -81,7 +81,7 @@ struct fsm_callbacks {
void (*SendTerminateAck) (struct fsm *, u_char); /* Send Term ACK please */
void (*DecodeConfig) (struct fsm *, u_char *, int, int, struct fsm_decode *);
/* Deal with incoming data */
- void (*RecvResetReq) (struct fsm *fp); /* Reset output */
+ int (*RecvResetReq) (struct fsm *fp); /* Reset output */
void (*RecvResetAck) (struct fsm *fp, u_char); /* Reset input */
};
@@ -174,7 +174,7 @@ extern void fsm_Up(struct fsm *);
extern void fsm_Down(struct fsm *);
extern void fsm_Input(struct fsm *, struct mbuf *);
extern void fsm_Close(struct fsm *);
-extern void fsm_NullRecvResetReq(struct fsm *);
+extern int fsm_NullRecvResetReq(struct fsm *);
extern void fsm_NullRecvResetAck(struct fsm *, u_char);
extern void fsm_Reopen(struct fsm *);
extern void fsm2initial(struct fsm *);
diff --git a/usr.sbin/ppp/ppp/i4b.c b/usr.sbin/ppp/ppp/i4b.c
index 3409962eadd..4ad4ba93807 100644
--- a/usr.sbin/ppp/ppp/i4b.c
+++ b/usr.sbin/ppp/ppp/i4b.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: i4b.c,v 1.4 2000/08/16 13:53:58 brian Exp $
+ * $OpenBSD: i4b.c,v 1.5 2001/06/19 10:24:53 brian Exp $
*/
#include <sys/param.h>
@@ -293,6 +293,7 @@ i4b_device2iov(struct device *d, struct iovec *iov, int *niov,
static struct device basei4bdevice = {
I4B_DEVICE,
"i4b",
+ 0,
{ CD_REQUIRED, DEF_I4BCDDELAY },
i4b_AwaitCarrier,
NULL,
diff --git a/usr.sbin/ppp/ppp/iface.c b/usr.sbin/ppp/ppp/iface.c
index a27f7ee4666..5cc07d90441 100644
--- a/usr.sbin/ppp/ppp/iface.c
+++ b/usr.sbin/ppp/ppp/iface.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: iface.c,v 1.16 2001/06/04 16:09:28 brian Exp $
+ * $OpenBSD: iface.c,v 1.17 2001/06/19 10:24:54 brian Exp $
*/
#include <sys/param.h>
@@ -163,8 +163,9 @@ iface_Create(const char *name)
return NULL;
}
iface->name = strdup(name);
- iface->flags = ifm->ifm_flags;
iface->index = ifm->ifm_index;
+ iface->flags = ifm->ifm_flags;
+ iface->mtu = 0;
iface->in_addrs = 0;
iface->in_addr = NULL;
}
@@ -540,7 +541,7 @@ iface_Show(struct cmdargs const *arg)
if_flags[f].value);
flags &= ~if_flags[f].flag;
}
- prompt_Printf(arg->prompt, "> mtu %d has %d address%s:\n", arg->bundle->mtu,
+ prompt_Printf(arg->prompt, "> mtu %d has %d address%s:\n", iface->mtu,
iface->in_addrs, iface->in_addrs == 1 ? "" : "es");
for (f = 0; f < iface->in_addrs; f++) {
diff --git a/usr.sbin/ppp/ppp/iface.h b/usr.sbin/ppp/ppp/iface.h
index 16b2e55f8bf..0b703ddf6e3 100644
--- a/usr.sbin/ppp/ppp/iface.h
+++ b/usr.sbin/ppp/ppp/iface.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: iface.h,v 1.6 2001/03/28 09:52:56 brian Exp $
+ * $OpenBSD: iface.h,v 1.7 2001/06/19 10:24:54 brian Exp $
*/
struct ifa_msghdr;
@@ -39,6 +39,7 @@ struct iface {
char *name; /* Interface name (malloc'd) */
int index; /* Interface index */
int flags; /* Interface flags (IFF_*) */
+ int mtu; /* struct tuninfo MTU */
int in_addrs; /* How many in_addr's */
struct iface_addr *in_addr; /* Array of addresses (malloc'd) */
diff --git a/usr.sbin/ppp/ppp/ip.c b/usr.sbin/ppp/ppp/ip.c
index 87f4f4dc1ba..8961534286e 100644
--- a/usr.sbin/ppp/ppp/ip.c
+++ b/usr.sbin/ppp/ppp/ip.c
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: ip.c,v 1.32 2001/06/13 21:33:41 brian Exp $
+ * $OpenBSD: ip.c,v 1.33 2001/06/19 10:24:54 brian Exp $
*/
#include <sys/param.h>
@@ -906,6 +906,14 @@ ip_PushPacket(struct link *l, struct bundle *bundle)
if (ipcp->fsm.state != ST_OPENED)
return 0;
+ /*
+ * If ccp is not open but is required, do nothing.
+ */
+ if (l->ccp.fsm.state != ST_OPENED && ccp_Required(&l->ccp)) {
+ log_Printf(LogPHASE, "%s: Not transmitting... waiting for CCP\n", l->name);
+ return 0;
+ }
+
queue = ipcp->Queue + IPCP_QUEUES(ipcp) - 1;
do {
if (queue->top) {
diff --git a/usr.sbin/ppp/ppp/lcp.c b/usr.sbin/ppp/ppp/lcp.c
index bf2e59daa17..2d261c789b1 100644
--- a/usr.sbin/ppp/ppp/lcp.c
+++ b/usr.sbin/ppp/ppp/lcp.c
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: lcp.c,v 1.25 2001/06/13 21:33:41 brian Exp $
+ * $OpenBSD: lcp.c,v 1.26 2001/06/19 10:24:55 brian Exp $
*/
#include <sys/param.h>
@@ -177,7 +177,13 @@ lcp_ReportStatus(struct cmdargs const *arg)
(u_long)lcp->want_magic, lcp->want_mrru,
lcp->want_shortseq ? "on" : "off", lcp->my_reject);
- prompt_Printf(arg->prompt, "\n Defaults: MRU = %d, ", lcp->cfg.mru);
+ prompt_Printf(arg->prompt, "\n Defaults: MRU = %d (max %d), ",
+ lcp->cfg.mru, lcp->cfg.max_mru);
+ if (lcp->cfg.mtu)
+ prompt_Printf(arg->prompt, "MTU = %d (max %d), ",
+ lcp->cfg.mtu, lcp->cfg.max_mtu);
+ else
+ prompt_Printf(arg->prompt, "MTU = any (max %d), ", lcp->cfg.max_mtu);
prompt_Printf(arg->prompt, "ACCMAP = %08lx\n", (u_long)lcp->cfg.accmap);
prompt_Printf(arg->prompt, " LQR period = %us, ",
lcp->cfg.lqrperiod);
@@ -241,6 +247,9 @@ lcp_Init(struct lcp *lcp, struct bundle *bundle, struct link *l,
bundle, l, parent, &lcp_Callbacks, lcp_TimerNames);
lcp->cfg.mru = DEF_MRU;
+ lcp->cfg.max_mru = MAX_MRU;
+ lcp->cfg.mtu = 0;
+ lcp->cfg.max_mtu = MAX_MTU;
lcp->cfg.accmap = 0;
lcp->cfg.openmode = 1;
lcp->cfg.lqrperiod = DEF_LQRPERIOD;
@@ -266,11 +275,12 @@ lcp_Init(struct lcp *lcp, struct bundle *bundle, struct link *l,
void
lcp_Setup(struct lcp *lcp, int openmode)
{
+ struct physical *p = link2physical(lcp->fsm.link);
+ int phmtu = p ? physical_DeviceMTU(p) : 0;
+
lcp->fsm.open_mode = openmode;
- lcp->his_mru = lcp->fsm.bundle->cfg.mtu;
- if (!lcp->his_mru || lcp->his_mru > DEF_MRU)
- lcp->his_mru = DEF_MRU;
+ lcp->his_mru = DEF_MRU;
lcp->his_mrru = 0;
lcp->his_magic = 0;
lcp->his_lqrperiod = 0;
@@ -281,13 +291,13 @@ lcp_Setup(struct lcp *lcp, int openmode)
lcp->his_shortseq = 0;
lcp->want_mru = lcp->cfg.mru;
+ if (phmtu && lcp->want_mru > phmtu)
+ lcp->want_mru = phmtu;
lcp->want_mrru = lcp->fsm.bundle->ncp.mp.cfg.mrru;
lcp->want_shortseq = IsEnabled(lcp->fsm.bundle->ncp.mp.cfg.shortseq) ? 1 : 0;
lcp->want_acfcomp = IsEnabled(lcp->cfg.acfcomp) ? 1 : 0;
if (lcp->fsm.parent) {
- struct physical *p = link2physical(lcp->fsm.link);
-
lcp->his_accmap = 0xffffffff;
lcp->want_accmap = lcp->cfg.accmap;
lcp->his_protocomp = 0;
@@ -592,15 +602,15 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
{
/* Deal with incoming PROTO_LCP */
struct lcp *lcp = fsm2lcp(fp);
- int type, length, sz, pos, op, callback_req;
+ int type, length, sz, pos, op, callback_req, mru_req;
u_int32_t magic, accmap;
- u_short mtu, mru, proto;
+ u_short mru, phmtu, proto;
struct lqrreq *req;
char request[20], desc[22];
struct mp *mp;
struct physical *p = link2physical(fp->link);
- sz = op = callback_req = 0;
+ sz = op = callback_req = mru_req = 0;
while (plen >= sizeof(struct fsmconfig)) {
type = *cp;
@@ -626,7 +636,13 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
/* Ignore his previous reject so that we REQ next time */
lcp->his_reject &= ~(1 << type);
- if (mru < MIN_MRU) {
+ if (mru > MAX_MRU) {
+ /* Push him down to MAX_MRU */
+ lcp->his_mrru = MAX_MRU;
+ memcpy(dec->nakend, cp, 2);
+ ua_htons(&lcp->his_mrru, dec->nakend + 2);
+ dec->nakend += 4;
+ } else if (mru < MIN_MRU) {
/* Push him up to MIN_MRU */
lcp->his_mrru = MIN_MRU;
memcpy(dec->nakend, cp, 2);
@@ -664,28 +680,41 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
break;
case TY_MRU:
+ mru_req = 1;
ua_ntohs(cp + 2, &mru);
log_Printf(LogLCP, "%s %d\n", request, mru);
switch (mode_type) {
case MODE_REQ:
- mtu = lcp->fsm.bundle->cfg.mtu;
- if (mru < MIN_MRU || (!lcp->want_mrru && mru < mtu)) {
+ phmtu = p ? physical_DeviceMTU(p) : 0;
+ if (phmtu && mru > phmtu) {
+ lcp->his_mru = lcp->cfg.mtu ? lcp->cfg.mtu : phmtu;
+ memcpy(dec->nakend, cp, 2);
+ ua_htons(&lcp->his_mru, dec->nakend + 2);
+ dec->nakend += 4;
+ } if (mru > lcp->cfg.max_mtu) {
+ lcp->his_mru = lcp->cfg.mtu ? lcp->cfg.mtu : lcp->cfg.max_mtu;
+ memcpy(dec->nakend, cp, 2);
+ ua_htons(&lcp->his_mru, dec->nakend + 2);
+ dec->nakend += 4;
+ } else if (mru < MIN_MRU || mru < lcp->cfg.mtu) {
/* Push him up to MTU or MIN_MRU */
- lcp->his_mru = mru < mtu ? mtu : MIN_MRU;
+ lcp->his_mru = mru < lcp->cfg.mtu ? lcp->cfg.mtu : MIN_MRU;
memcpy(dec->nakend, cp, 2);
ua_htons(&lcp->his_mru, dec->nakend + 2);
dec->nakend += 4;
} else {
- lcp->his_mru = mtu ? mtu : mru;
+ lcp->his_mru = lcp->cfg.mtu ? lcp->cfg.mtu : mru;
memcpy(dec->ackend, cp, 4);
dec->ackend += 4;
}
break;
case MODE_NAK:
- if (mru > MAX_MRU)
- lcp->want_mru = MAX_MRU;
- else if (mru < MIN_MRU)
+ if (mru > lcp->cfg.max_mru) {
+ lcp->want_mru = lcp->cfg.max_mru;
+ if (p && lcp->want_mru > physical_DeviceMTU(p))
+ lcp->want_mru = physical_DeviceMTU(p);
+ } else if (mru < MIN_MRU)
lcp->want_mru = MIN_MRU;
else
lcp->want_mru = mru;
@@ -1217,6 +1246,22 @@ reqreject:
dec->nakend[-1] = 2; /* XXX: Silly ! */
}
}
+ if (mode_type == MODE_REQ && !mru_req) {
+ mru = DEF_MRU;
+ phmtu = p ? physical_DeviceMTU(p) : 0;
+ if (phmtu && mru > phmtu)
+ mru = phmtu;
+ if (mru > lcp->cfg.max_mtu)
+ mru = lcp->cfg.max_mtu;
+ if (mru < DEF_MRU) {
+ /* Don't let the peer use the default MRU */
+ lcp->his_mru = lcp->cfg.mtu && lcp->cfg.mtu < mru ? lcp->cfg.mtu : mru;
+ *dec->nakend++ = TY_MRU;
+ *dec->nakend++ = 4;
+ ua_htons(&lcp->his_mru, dec->nakend);
+ dec->nakend += 2;
+ }
+ }
if (dec->rejend != dec->rej) {
/* rejects are preferred */
dec->ackend = dec->ack;
diff --git a/usr.sbin/ppp/ppp/lcp.h b/usr.sbin/ppp/ppp/lcp.h
index b9ab2bc7cb0..505634ca7d7 100644
--- a/usr.sbin/ppp/ppp/lcp.h
+++ b/usr.sbin/ppp/ppp/lcp.h
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: lcp.h,v 1.9 2001/06/13 21:33:41 brian Exp $
+ * $OpenBSD: lcp.h,v 1.10 2001/06/19 10:24:55 brian Exp $
*/
/* callback::opmask values */
@@ -82,6 +82,9 @@ struct lcp {
struct {
u_short mru; /* Preferred MRU value */
+ u_short max_mru; /* Preferred MRU value */
+ u_short mtu; /* Preferred MTU */
+ u_short max_mtu; /* Preferred MTU */
u_int32_t accmap; /* Initial ACCMAP value */
int openmode; /* when to start CFG REQs */
u_int32_t lqrperiod; /* LQR frequency (seconds) */
diff --git a/usr.sbin/ppp/ppp/mppe.c b/usr.sbin/ppp/ppp/mppe.c
index 97e03a6edff..b2e4392fbd2 100644
--- a/usr.sbin/ppp/ppp/mppe.c
+++ b/usr.sbin/ppp/ppp/mppe.c
@@ -23,13 +23,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: mppe.c,v 1.5 2001/02/04 22:53:13 brian Exp $
+ * $OpenBSD: mppe.c,v 1.6 2001/06/19 10:24:56 brian Exp $
*/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <termios.h>
#ifdef __FreeBSD__
#include <sha.h>
@@ -61,23 +62,53 @@
* draft-ietf-pppext-mppe-keys-02.txt
*/
+#define MPPE_OPT_STATELESS 0x1000000
+#define MPPE_OPT_COMPRESSED 0x01
+#define MPPE_OPT_40BIT 0x20
+#define MPPE_OPT_56BIT 0x80
+#define MPPE_OPT_128BIT 0x40
+#define MPPE_OPT_BITMASK 0xe0
+#define MPPE_OPT_MASK (MPPE_OPT_STATELESS | MPPE_OPT_BITMASK)
+
+#define MPPE_FLUSHED 0x8000
+#define MPPE_ENCRYPTED 0x1000
+#define MPPE_HEADER_BITMASK 0xf000
+#define MPPE_HEADER_FLAG 0x00ff
+#define MPPE_HEADER_FLAGMASK 0x00ff
+#define MPPE_HEADER_FLAGSHIFT 8
+
struct mppe_state {
- int cohnum;
- int keylen; /* 8 or 16 bytes */
- int keybits; /* 40, 56 or 128 bits */
- char sesskey[MPPE_KEY_LEN];
- char mastkey[MPPE_KEY_LEN];
- RC4_KEY rc4key;
+ unsigned stateless : 1;
+ unsigned flushnext : 1;
+ unsigned flushrequired : 1;
+ int cohnum;
+ int keylen; /* 8 or 16 bytes */
+ int keybits; /* 40, 56 or 128 bits */
+ char sesskey[MPPE_KEY_LEN];
+ char mastkey[MPPE_KEY_LEN];
+ RC4_KEY rc4key;
};
int MPPE_MasterKeyValid = 0;
int MPPE_IsServer = 0;
char MPPE_MasterKey[MPPE_KEY_LEN];
-static void
+/*
+ * The peer has missed a packet. Mark the next output frame to be FLUSHED
+ */
+static int
MPPEResetOutput(void *v)
{
- log_Printf(LogCCP, "MPPE: Output channel reset\n");
+ struct mppe_state *mop = (struct mppe_state *)v;
+
+ if (mop->stateless)
+ log_Printf(LogCCP, "MPPE: Unexpected output channel reset\n");
+ else {
+ log_Printf(LogCCP, "MPPE: Output channel reset\n");
+ mop->flushnext = 1;
+ }
+
+ return 0; /* Ask FSM not to ACK */
}
static void
@@ -112,17 +143,18 @@ MPPEOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short *proto,
{
struct mppe_state *mop = (struct mppe_state *)v;
struct mbuf *mo;
- u_short nproto;
- int ilen;
+ u_short nproto, prefix;
+ int dictinit, ilen, len;
char *rp;
- log_Printf(LogCCP, "MPPE: Output\n");
-
ilen = m_length(mp);
+ dictinit = 0;
log_Printf(LogDEBUG, "MPPE: Output: Proto %02x (%d bytes)\n", *proto, ilen);
if (*proto < 0x21 && *proto > 0xFA) {
log_Printf(LogDEBUG, "MPPE: Output: Not encrypting\n");
+ ccp->compout += ilen;
+ ccp->uncompout += ilen;
return mp;
}
@@ -132,12 +164,32 @@ MPPEOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short *proto,
mo = m_get(4, MB_CCPOUT);
mo->m_next = mp;
- /* Init RC4 keys */
- RC4_set_key(&mop->rc4key, mop->keylen, mop->sesskey);
+ rp = MBUF_CTOP(mo);
+ prefix = MPPE_ENCRYPTED | mop->cohnum;
+
+ if (mop->stateless ||
+ (mop->cohnum & MPPE_HEADER_FLAGMASK) == MPPE_HEADER_FLAG) {
+ /* Change our key */
+ log_Printf(LogDEBUG, "MPPEOutput: Key changed [%d]\n", mop->cohnum);
+ MPPEKeyChange(mop);
+ dictinit = 1;
+ }
+
+ if (mop->stateless || mop->flushnext) {
+ prefix |= MPPE_FLUSHED;
+ dictinit = 1;
+ mop->flushnext = 0;
+ }
+
+ if (dictinit) {
+ /* Initialise our dictionary */
+ log_Printf(LogDEBUG, "MPPEOutput: Dictionary initialised [%d]\n",
+ mop->cohnum);
+ RC4_set_key(&mop->rc4key, mop->keylen, mop->sesskey);
+ }
/* Set MPPE packet prefix */
- rp = MBUF_CTOP(mo);
- *(u_short *)rp = htons(0x9000 | mop->cohnum);
+ *(u_short *)rp = htons(prefix);
/* Save encrypted protocol number */
nproto = htons(*proto);
@@ -147,15 +199,17 @@ MPPEOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short *proto,
rp = MBUF_CTOP(mp);
RC4(&mop->rc4key, ilen, rp, rp);
- /* Rotate keys */
- MPPEKeyChange(mop);
- mop->cohnum ++; mop->cohnum &= 0xFFF;
+ mop->cohnum++;
+ mop->cohnum &= ~MPPE_HEADER_BITMASK;
- /* Chage protocol number */
+ /* Set the protocol number */
*proto = ccp_Proto(ccp);
+ len = m_length(mo);
+ ccp->uncompout += ilen;
+ ccp->compout += len;
log_Printf(LogDEBUG, "MPPE: Output: Encrypted: Proto %02x (%d bytes)\n",
- *proto, m_length(mo));
+ *proto, len);
return mo;
}
@@ -163,7 +217,7 @@ MPPEOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short *proto,
static void
MPPEResetInput(void *v)
{
- log_Printf(LogCCP, "MPPE: Input channel reset\n");
+ log_Printf(LogCCP, "MPPE: Unexpected input channel ack\n");
}
static struct mbuf *
@@ -172,43 +226,126 @@ MPPEInput(void *v, struct ccp *ccp, u_short *proto, struct mbuf *mp)
struct mppe_state *mip = (struct mppe_state *)v;
u_short prefix;
char *rp;
- int ilen;
-
- log_Printf(LogCCP, "MPPE: Input\n");
+ int dictinit, flushed, ilen, len, n;
ilen = m_length(mp);
+ dictinit = 0;
+ ccp->compin += ilen;
log_Printf(LogDEBUG, "MPPE: Input: Proto %02x (%d bytes)\n", *proto, ilen);
-
log_DumpBp(LogDEBUG, "MPPE: Input: Packet:", mp);
mp = mbuf_Read(mp, &prefix, 2);
prefix = ntohs(prefix);
- if ((prefix & 0xF000) != 0x9000) {
- log_Printf(LogERROR, "MPPE: Input: Invalid packet\n");
+ flushed = prefix & MPPE_FLUSHED;
+ prefix &= ~flushed;
+ if ((prefix & MPPE_HEADER_BITMASK) != MPPE_ENCRYPTED) {
+ log_Printf(LogERROR, "MPPE: Input: Invalid packet (flags = 0x%x)\n",
+ (prefix & MPPE_HEADER_BITMASK) | flushed);
m_freem(mp);
return NULL;
}
- prefix &= 0xFFF;
- while (prefix != mip->cohnum) {
- MPPEKeyChange(mip);
- mip->cohnum ++; mip->cohnum &= 0xFFF;
+ prefix &= ~MPPE_HEADER_BITMASK;
+
+ if (!flushed && mip->stateless) {
+ log_Printf(LogCCP, "MPPEInput: Packet without MPPE_FLUSHED set"
+ " in stateless mode\n");
+ flushed = MPPE_FLUSHED;
+ /* Should we really continue ? */
+ }
+
+ if (mip->stateless) {
+ /* Change our key for each missed packet in stateless mode */
+ while (prefix != mip->cohnum) {
+ log_Printf(LogDEBUG, "MPPEInput: Key changed [%u]\n", prefix);
+ MPPEKeyChange(mip);
+ /*
+ * mip->cohnum contains what we received last time in stateless
+ * mode.
+ */
+ mip->cohnum++;
+ mip->cohnum &= ~MPPE_HEADER_BITMASK;
+ }
+ dictinit = 1;
+ } else {
+ if (flushed) {
+ /*
+ * We can always process a flushed packet.
+ * Catch up on any outstanding key changes.
+ */
+ n = (prefix >> MPPE_HEADER_FLAGSHIFT) -
+ (mip->cohnum >> MPPE_HEADER_FLAGSHIFT);
+ while (n--) {
+ log_Printf(LogDEBUG, "MPPEInput: Key changed during catchup [%u]\n",
+ prefix);
+ MPPEKeyChange(mip);
+ }
+ mip->flushrequired = 0;
+ mip->cohnum = prefix;
+ dictinit = 1;
+ }
+
+ if (mip->flushrequired) {
+ /*
+ * Perhaps we should be lenient if
+ * (prefix & MPPE_HEADER_FLAGMASK) == MPPE_HEADER_FLAG
+ * The spec says that we shouldn't be though....
+ */
+ log_Printf(LogDEBUG, "MPPE: Not flushed - discarded\n");
+ m_freem(mp);
+ return NULL;
+ }
+
+ if (prefix != mip->cohnum) {
+ /*
+ * We're in stateful mode and didn't receive the expected
+ * packet. Send a reset request, but don't tell the CCP layer
+ * about it as we don't expect to receive a Reset ACK !
+ * Guess what... M$ invented this !
+ */
+ log_Printf(LogCCP, "MPPE: Input: Got seq %u, not %u\n",
+ prefix, mip->cohnum);
+ fsm_Output(&ccp->fsm, CODE_RESETREQ, ccp->fsm.reqid++, NULL, 0,
+ MB_CCPOUT);
+ mip->flushrequired = 1;
+ m_freem(mp);
+ return NULL;
+ }
+
+ if ((prefix & MPPE_HEADER_FLAGMASK) == MPPE_HEADER_FLAG) {
+ log_Printf(LogDEBUG, "MPPEInput: Key changed [%u]\n", prefix);
+ MPPEKeyChange(mip);
+ dictinit = 1;
+ } else if (flushed)
+ dictinit = 1;
+
+ /*
+ * mip->cohnum contains what we expect to receive next time in stateful
+ * mode.
+ */
+ mip->cohnum++;
+ mip->cohnum &= ~MPPE_HEADER_BITMASK;
}
- RC4_set_key(&mip->rc4key, mip->keylen, mip->sesskey);
+ if (dictinit) {
+ log_Printf(LogDEBUG, "MPPEInput: Dictionary initialised [%u]\n", prefix);
+ RC4_set_key(&mip->rc4key, mip->keylen, mip->sesskey);
+ }
mp = mbuf_Read(mp, proto, 2);
RC4(&mip->rc4key, 2, (char *)proto, (char *)proto);
*proto = ntohs(*proto);
rp = MBUF_CTOP(mp);
- RC4(&mip->rc4key, m_length(mp), rp, rp);
+ len = m_length(mp);
+ RC4(&mip->rc4key, len, rp, rp);
- log_Printf(LogDEBUG, "MPPE: Input: Decrypted: Proto %02x (%d bytes)\n",
- *proto, m_length(mp));
+ log_Printf(LogDEBUG, "MPPEInput: Decrypted: Proto %02x (%d bytes)\n",
+ *proto, len);
+ log_DumpBp(LogDEBUG, "MPPEInput: Decrypted: Packet:", mp);
- log_DumpBp(LogDEBUG, "MPPE: Input: Decrypted: Packet:", mp);
+ ccp->uncompin += len;
return mp;
}
@@ -216,14 +353,51 @@ MPPEInput(void *v, struct ccp *ccp, u_short *proto, struct mbuf *mp)
static void
MPPEDictSetup(void *v, struct ccp *ccp, u_short proto, struct mbuf *mi)
{
- log_Printf(LogCCP, "MPPE: DictSetup\n");
}
static const char *
MPPEDispOpts(struct lcp_opt *o)
{
- static char buf[32];
- sprintf(buf, "value 0x%08x", (int)ntohl(*(u_int32_t *)(o->data)));
+ static char buf[70];
+ u_int32_t val = ntohl(*(u_int32_t *)o->data);
+ char ch;
+ int len;
+
+ snprintf(buf, sizeof buf, "value 0x%08x ", (unsigned)val);
+ len = strlen(buf);
+ if (!(val & MPPE_OPT_BITMASK)) {
+ snprintf(buf + len, sizeof buf - len, "(0");
+ len++;
+ } else {
+ ch = '(';
+ if (val & MPPE_OPT_128BIT) {
+ snprintf(buf + len, sizeof buf - len, "%c128", ch);
+ len += strlen(buf + len);
+ ch = '/';
+ }
+ if (val & MPPE_OPT_56BIT) {
+ snprintf(buf + len, sizeof buf - len, "%c56", ch);
+ len += strlen(buf + len);
+ ch = '/';
+ }
+ if (val & MPPE_OPT_40BIT) {
+ snprintf(buf + len, sizeof buf - len, "%c40", ch);
+ len += strlen(buf + len);
+ ch = '/';
+ }
+ }
+
+ snprintf(buf + len, sizeof buf - len, " bits, state%s",
+ (val & MPPE_OPT_STATELESS) ? "less" : "full");
+ len += strlen(buf + len);
+
+ if (val & MPPE_OPT_COMPRESSED) {
+ snprintf(buf + len, sizeof buf - len, ", compressed");
+ len += strlen(buf + len);
+ }
+
+ snprintf(buf + len, sizeof buf - len, ")");
+
return buf;
}
@@ -242,120 +416,213 @@ MPPEUsable(struct fsm *fp)
return ok;
}
+static int
+MPPERequired(struct fsm *fp)
+{
+ return fp->link->ccp.cfg.mppe.required;
+}
+
+static u_int32_t
+MPPE_ConfigVal(const struct ccp_config *cfg)
+{
+ u_int32_t val;
+
+ val = cfg->mppe.state == MPPE_STATELESS ? MPPE_OPT_STATELESS : 0;
+ switch(cfg->mppe.keybits) {
+ case 128:
+ val |= MPPE_OPT_128BIT;
+ break;
+ case 56:
+ val |= MPPE_OPT_56BIT;
+ break;
+ case 40:
+ val |= MPPE_OPT_40BIT;
+ break;
+ case 0:
+ val |= MPPE_OPT_128BIT | MPPE_OPT_56BIT | MPPE_OPT_40BIT;
+ break;
+ }
+
+ return val;
+}
+
+/*
+ * What options should we use for our first configure request
+ */
static void
MPPEInitOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg)
{
- u_long val;
+ u_int32_t *p = (u_int32_t *)o->data;
o->len = 6;
- log_Printf(LogCCP, "MPPE: InitOptsOutput\n");
-
if (!MPPE_MasterKeyValid) {
log_Printf(LogCCP, "MPPE: MasterKey is invalid,"
" MPPE is available only with CHAP81 authentication\n");
- *(u_int32_t *)o->data = htonl(0x0);
+ *p = htonl(0x0);
return;
}
- val = 0x1000000;
- switch(cfg->mppe.keybits) {
- case 128:
- val |= 0x40; break;
- case 56:
- val |= 0x80; break;
- case 40:
- val |= 0x20; break;
- }
- *(u_int32_t *)o->data = htonl(val);
+ *p = htonl(MPPE_ConfigVal(cfg));
}
+/*
+ * Our CCP request was NAK'd with the given options
+ */
static int
-MPPESetOptsOutput(struct lcp_opt *o)
+MPPESetOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg)
{
- u_long *p = (u_long *)(o->data);
- u_long val = ntohl(*p);
-
- log_Printf(LogCCP, "MPPE: SetOptsOutput\n");
+ u_int32_t *p = (u_int32_t *)o->data;
+ u_int32_t peer = ntohl(*p);
+ u_int32_t mval;
+
+ if (!MPPE_MasterKeyValid)
+ /* Treat their NAK as a REJ */
+ return MODE_NAK;
+
+ mval = MPPE_ConfigVal(cfg);
+
+ /*
+ * If we haven't been configured with a specific number of keybits, allow
+ * whatever the peer asks for.
+ */
+ if (!cfg->mppe.keybits) {
+ mval &= ~MPPE_OPT_BITMASK;
+ mval |= (peer & MPPE_OPT_BITMASK);
+ if (!(mval & MPPE_OPT_BITMASK))
+ mval |= MPPE_OPT_128BIT;
+ }
- if (!MPPE_MasterKeyValid) {
- if (*p != 0x0) {
- *p = 0x0;
- return MODE_NAK;
- } else {
- return MODE_ACK;
- }
+ /* Adjust our statelessness */
+ if (cfg->mppe.state == MPPE_ANYSTATE) {
+ mval &= ~MPPE_OPT_STATELESS;
+ mval |= (peer & MPPE_OPT_STATELESS);
}
- if (val == 0x01000020 ||
- val == 0x01000040 ||
- val == 0x01000080)
- return MODE_ACK;
+ *p = htonl(mval);
- return MODE_NAK;
+ return MODE_ACK;
}
+/*
+ * The peer has requested the given options
+ */
static int
MPPESetOptsInput(struct lcp_opt *o, const struct ccp_config *cfg)
{
- u_long *p = (u_long *)(o->data);
- u_long val = ntohl(*p);
- u_long mval;
-
- log_Printf(LogCCP, "MPPE: SetOptsInput\n");
+ u_int32_t *p = (u_int32_t *)(o->data);
+ u_int32_t peer = ntohl(*p);
+ u_int32_t mval;
+ int res = MODE_ACK;
if (!MPPE_MasterKeyValid) {
if (*p != 0x0) {
*p = 0x0;
return MODE_NAK;
- } else {
+ } else
return MODE_ACK;
- }
}
- mval = 0x01000000;
- switch(cfg->mppe.keybits) {
- case 128:
- mval |= 0x40; break;
- case 56:
- mval |= 0x80; break;
- case 40:
- mval |= 0x20; break;
+ mval = MPPE_ConfigVal(cfg);
+
+ if (peer & ~MPPE_OPT_MASK)
+ /* He's asking for bits we don't know about */
+ res = MODE_NAK;
+
+ if (peer & MPPE_OPT_STATELESS) {
+ if (cfg->mppe.state == MPPE_STATEFUL)
+ /* Peer can't have stateless */
+ res = MODE_NAK;
+ else
+ /* Peer wants stateless, that's ok */
+ mval |= MPPE_OPT_STATELESS;
+ } else {
+ if (cfg->mppe.state == MPPE_STATELESS)
+ /* Peer must have stateless */
+ res = MODE_NAK;
+ else
+ /* Peer doesn't want stateless, that's ok */
+ mval &= ~MPPE_OPT_STATELESS;
}
- if (val == mval)
- return MODE_ACK;
+ /* If we've got a configured number of keybits - the peer must use that */
+ if (cfg->mppe.keybits) {
+ *p = htonl(mval);
+ return peer == mval ? res : MODE_NAK;
+ }
+ /* If a specific number of bits hasn't been requested, we'll need to NAK */
+ switch (peer & MPPE_OPT_BITMASK) {
+ case MPPE_OPT_128BIT:
+ case MPPE_OPT_56BIT:
+ case MPPE_OPT_40BIT:
+ break;
+ default:
+ res = MODE_NAK;
+ }
+
+ /* Suggest the best number of bits */
+ mval &= ~MPPE_OPT_BITMASK;
+ if (peer & MPPE_OPT_128BIT)
+ mval |= MPPE_OPT_128BIT;
+ else if (peer & MPPE_OPT_56BIT)
+ mval |= MPPE_OPT_56BIT;
+ else if (peer & MPPE_OPT_40BIT)
+ mval |= MPPE_OPT_40BIT;
+ else
+ mval |= MPPE_OPT_128BIT;
*p = htonl(mval);
- return MODE_NAK;
+ return res;
+}
+
+static struct mppe_state *
+MPPE_InitState(struct lcp_opt *o)
+{
+ struct mppe_state *mp;
+ u_int32_t val;
+
+ if ((mp = calloc(1, sizeof *mp)) != NULL) {
+ val = ntohl(*(u_int32_t *)o->data);
+
+ switch (val & MPPE_OPT_BITMASK) {
+ case MPPE_OPT_128BIT:
+ mp->keylen = 16;
+ mp->keybits = 128;
+ break;
+ case MPPE_OPT_56BIT:
+ mp->keylen = 8;
+ mp->keybits = 56;
+ break;
+ case MPPE_OPT_40BIT:
+ mp->keylen = 8;
+ mp->keybits = 40;
+ break;
+ default:
+ log_Printf(LogWARN, "Unexpected MPPE options 0x%08x\n", val);
+ free(mp);
+ return NULL;
+ }
+
+ mp->stateless = !!(val & MPPE_OPT_STATELESS);
+ }
+
+ return mp;
}
static void *
MPPEInitInput(struct lcp_opt *o)
{
struct mppe_state *mip;
- u_int32_t val = ntohl(*(unsigned long *)o->data);
-
- log_Printf(LogCCP, "MPPE: InitInput\n");
if (!MPPE_MasterKeyValid) {
log_Printf(LogWARN, "MPPE: Cannot initialise without CHAP81\n");
return NULL;
}
- mip = malloc(sizeof(*mip));
- memset(mip, 0, sizeof(*mip));
-
- if (val & 0x20) { /* 40-bits */
- mip->keylen = 8;
- mip->keybits = 40;
- } else if (val & 0x80) { /* 56-bits */
- mip->keylen = 8;
- mip->keybits = 56;
- } else { /* 128-bits */
- mip->keylen = 16;
- mip->keybits = 128;
+ if ((mip = MPPE_InitState(o)) == NULL) {
+ log_Printf(LogWARN, "MPPEInput: Cannot initialise - unexpected options\n");
+ return NULL;
}
log_Printf(LogDEBUG, "MPPE: InitInput: %d-bits\n", mip->keybits);
@@ -366,9 +633,25 @@ MPPEInitInput(struct lcp_opt *o)
MPPEReduceSessionKey(mip);
- MPPEKeyChange(mip);
-
- mip->cohnum = 0;
+ log_Printf(LogCCP, "MPPE: Input channel initiated\n");
+
+ if (!mip->stateless) {
+ /*
+ * We need to initialise our dictionary here as the first packet we
+ * receive is unlikely to have the FLUSHED bit set.
+ */
+ log_Printf(LogDEBUG, "MPPEInitInput: Dictionary initialised [%d]\n",
+ mip->cohnum);
+ RC4_set_key(&mip->rc4key, mip->keylen, mip->sesskey);
+ } else {
+ /*
+ * We do the first key change here as the first packet is expected
+ * to have a sequence number of 0 and we'll therefore not expect
+ * to have to change the key at that point.
+ */
+ log_Printf(LogDEBUG, "MPPEInitInput: Key changed [%d]\n", mip->cohnum);
+ MPPEKeyChange(mip);
+ }
return mip;
}
@@ -377,27 +660,15 @@ static void *
MPPEInitOutput(struct lcp_opt *o)
{
struct mppe_state *mop;
- u_int32_t val = ntohl(*(unsigned long *)o->data);
-
- log_Printf(LogCCP, "MPPE: InitOutput\n");
if (!MPPE_MasterKeyValid) {
log_Printf(LogWARN, "MPPE: Cannot initialise without CHAP81\n");
return NULL;
}
- mop = malloc(sizeof(*mop));
- memset(mop, 0, sizeof(*mop));
-
- if (val & 0x20) { /* 40-bits */
- mop->keylen = 8;
- mop->keybits = 40;
- } else if (val & 0x80) { /* 56-bits */
- mop->keylen = 8;
- mop->keybits = 56;
- } else { /* 128-bits */
- mop->keylen = 16;
- mop->keybits = 128;
+ if ((mop = MPPE_InitState(o)) == NULL) {
+ log_Printf(LogWARN, "MPPEOutput: Cannot initialise - unexpected options\n");
+ return NULL;
}
log_Printf(LogDEBUG, "MPPE: InitOutput: %d-bits\n", mop->keybits);
@@ -408,9 +679,17 @@ MPPEInitOutput(struct lcp_opt *o)
MPPEReduceSessionKey(mop);
- MPPEKeyChange(mop);
+ log_Printf(LogCCP, "MPPE: Output channel initiated\n");
- mop->cohnum = 0;
+ if (!mop->stateless) {
+ /*
+ * We need to initialise our dictionary now as the first packet we
+ * send won't have the FLUSHED bit set.
+ */
+ log_Printf(LogDEBUG, "MPPEInitOutput: Dictionary initialised [%d]\n",
+ mop->cohnum);
+ RC4_set_key(&mop->rc4key, mop->keylen, mop->sesskey);
+ }
return mop;
}
@@ -418,14 +697,12 @@ MPPEInitOutput(struct lcp_opt *o)
static void
MPPETermInput(void *v)
{
- log_Printf(LogCCP, "MPPE: TermInput\n");
free(v);
}
static void
MPPETermOutput(void *v)
{
- log_Printf(LogCCP, "MPPE: TermOutput\n");
free(v);
}
@@ -434,6 +711,7 @@ const struct ccp_algorithm MPPEAlgorithm = {
CCP_NEG_MPPE,
MPPEDispOpts,
MPPEUsable,
+ MPPERequired,
{
MPPESetOptsInput,
MPPEInitInput,
diff --git a/usr.sbin/ppp/ppp/physical.c b/usr.sbin/ppp/ppp/physical.c
index 89332e6421d..2d13943e7aa 100644
--- a/usr.sbin/ppp/ppp/physical.c
+++ b/usr.sbin/ppp/ppp/physical.c
@@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $OpenBSD: physical.c,v 1.29 2001/03/24 01:06:03 brian Exp $
+ * $OpenBSD: physical.c,v 1.30 2001/06/19 10:24:56 brian Exp $
*
*/
@@ -758,6 +758,12 @@ physical_IsSync(struct physical *p)
return p->cfg.speed == 0;
}
+u_short
+physical_DeviceMTU(struct physical *p)
+{
+ return p->handler ? p->handler->mtu : 0;
+}
+
const char *physical_GetDevice(struct physical *p)
{
return p->name.full;
diff --git a/usr.sbin/ppp/ppp/physical.h b/usr.sbin/ppp/ppp/physical.h
index 4816093b5a4..34025a577b2 100644
--- a/usr.sbin/ppp/ppp/physical.h
+++ b/usr.sbin/ppp/ppp/physical.h
@@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $OpenBSD: physical.h,v 1.17 2000/09/14 22:02:50 brian Exp $
+ * $OpenBSD: physical.h,v 1.18 2001/06/19 10:24:56 brian Exp $
*
*/
@@ -56,6 +56,7 @@ struct cd {
struct device {
int type;
const char *name;
+ u_short mtu;
struct cd cd;
int (*awaitcarrier)(struct physical *);
@@ -143,6 +144,7 @@ extern const char *physical_LockedDevice(struct physical *);
extern void physical_ChangedPid(struct physical *, pid_t);
extern int physical_IsSync(struct physical *);
+extern u_short physical_DeviceMTU(struct physical *);
extern const char *physical_GetDevice(struct physical *);
extern void physical_SetDeviceList(struct physical *, int, const char *const *);
extern void physical_SetDevice(struct physical *, const char *);
diff --git a/usr.sbin/ppp/ppp/ppp.8 b/usr.sbin/ppp/ppp/ppp.8
index 131a966df5c..ded98a9554c 100644
--- a/usr.sbin/ppp/ppp/ppp.8
+++ b/usr.sbin/ppp/ppp/ppp.8
@@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $OpenBSD: ppp.8,v 1.111 2001/06/07 09:32:55 brian Exp $
+.\" $OpenBSD: ppp.8,v 1.112 2001/06/19 10:24:57 brian Exp $
.\"
.Dd September 20, 1995
.Dt PPP 8
@@ -4910,39 +4910,93 @@ This will allow
to do the necessary address translations to enable the process that
triggers the connection to connect once the link is up despite the
peer assigning us a new (dynamic) IP address.
-.It set mppe {40|56|128}
-This option selects particular key length. Default is 128.
+.It set mppe Op 40|56|128|* Op stateless|statefull|*
+This option selects the encryption parameters used when negotiation
+MPPE. MPPE can be disabled entirely with the
+.Dq disable mppe
+command.
+If no arguments are given,
+.Nm
+will attempt to negotiate a statefull link with a 128 bit key, but
+will agree to whatever the peer requests (including no encryption
+at all).
+.Pp
+If any arguments are given,
+.Nm
+will
+.Em insist
+on using MPPE and will close the link if it's rejected by the peer.
+.Pp
+The first argument specifies the number of bits that
+.Nm
+should insist on during negotiations and the second specifies whether
+.Nm
+should insist on statefull or stateless mode. In stateless mode, the
+encryption dictionary is re-initialised with every packet according to
+an encryption key that is changed with every packet. In statefull mode,
+the encryption dictionary is re-initialised every 256 packets or after
+the loss of any data and the key is changed every 256 packets.
+Stateless mode is less efficient but is better for unreliable transport
+layers.
.It set mrru Op Ar value
Setting this option enables Multi-link PPP negotiations, also known as
Multi-link Protocol or MP.
There is no default MRRU (Maximum Reconstructed Receive Unit) value.
If no argument is given, multi-link mode is disabled.
-.It set mru Op Ar value
+.It set mru Oo max Ns Oo imum Oc Oc Op Ar value
The default MRU (Maximum Receive Unit) is 1500.
If it is increased, the other side *may* increase its MTU.
-There is no point in decreasing the MRU to below the default as the
+In theory there is no point in decreasing the MRU to below the default as the
.Em PPP
-protocol *must* be able to accept packets of at least 1500 octets.
+protocol says implementations *must* be able to accept packets of at
+least 1500 octets.
+.Pp
+If the
+.Dq maximum
+keyword is used,
+.Nm
+will refuse to negotiate a higher value.
+The maximum MRU can be set to 2048 at most.
+Setting a maximum of less than 1500 violates the
+.Em PPP
+rfc, but may sometimes be necessary.
+For example,
+.Em PPPoE
+imposes a maximum of 1492 due to hardware limitations.
+.Pp
If no argument is given, 1500 is assumed.
-.It set mtu Op Ar value
+A value must be given when
+.Dq maximum
+is specified.
+.It set mtu Oo max Ns Oo imum Oc Oc Op Ar value
The default MTU is 1500.
At negotiation time,
.Nm
-will accept whatever MRU or MRRU that the peer wants (assuming it's
-not less than 296 bytes).
+will accept whatever MRU the peer requests (assuming it's
+not less than 296 bytes or greater than the assigned maximum).
If the MTU is set,
.Nm
-will not accept MRU/MRRU values less than
+will not accept MRU values less than
.Ar value .
-When negotiations are complete, the MTU is assigned to the interface, even
-if the peer requested a higher value MRU/MRRU.
+When negotiations are complete, the MTU is used when writing to the
+interface, even if the peer requested a higher value MRU.
This can be useful for
limiting your packet size (giving better bandwidth sharing at the expense
of more header data).
.Pp
+If the
+.Dq maximum
+keyword is used,
+.Nm
+will refuse to negotiate a higher value.
+The maximum MTU can be set to 2048 at most.
+.Pp
If no
.Ar value
is given, 1500, or whatever the peer asks for is used.
+A value must be given when
+.Dq maximum
+is specified.
.It set nbns Op Ar x.x.x.x Op Ar y.y.y.y
This option allows the setting of the Microsoft NetBIOS name server
values to be returned at the peers request.
diff --git a/usr.sbin/ppp/ppp/pred.c b/usr.sbin/ppp/ppp/pred.c
index 5645b53cba9..c6b6150ce8f 100644
--- a/usr.sbin/ppp/ppp/pred.c
+++ b/usr.sbin/ppp/ppp/pred.c
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: pred.c,v 1.10 2001/02/04 22:53:13 brian Exp $
+ * $OpenBSD: pred.c,v 1.11 2001/06/19 10:24:57 brian Exp $
*/
#include <sys/types.h>
@@ -139,13 +139,15 @@ Pred1ResetInput(void *v)
log_Printf(LogCCP, "Predictor1: Input channel reset\n");
}
-static void
+static int
Pred1ResetOutput(void *v)
{
struct pred1_state *state = (struct pred1_state *)v;
state->hash = 0;
memset(state->dict, '\0', sizeof state->dict);
log_Printf(LogCCP, "Predictor1: Output channel reset\n");
+
+ return 1; /* Ask FSM to ACK */
}
static void *
@@ -304,7 +306,7 @@ Pred1InitOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg)
}
static int
-Pred1SetOptsOutput(struct lcp_opt *o)
+Pred1SetOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg)
{
if (o->len != 2) {
o->len = 2;
@@ -316,14 +318,19 @@ Pred1SetOptsOutput(struct lcp_opt *o)
static int
Pred1SetOptsInput(struct lcp_opt *o, const struct ccp_config *cfg)
{
- return Pred1SetOptsOutput(o);
+ if (o->len != 2) {
+ o->len = 2;
+ return MODE_NAK;
+ }
+ return MODE_ACK;
}
const struct ccp_algorithm Pred1Algorithm = {
TY_PRED1,
CCP_NEG_PRED1,
Pred1DispOpts,
- ccp_IsUsable,
+ ccp_DefaultUsable,
+ ccp_DefaultRequired,
{
Pred1SetOptsInput,
Pred1InitInput,
diff --git a/usr.sbin/ppp/ppp/route.c b/usr.sbin/ppp/ppp/route.c
index 3334a985080..515c5dfcb5f 100644
--- a/usr.sbin/ppp/ppp/route.c
+++ b/usr.sbin/ppp/ppp/route.c
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: route.c,v 1.12 2001/06/13 21:33:42 brian Exp $
+ * $OpenBSD: route.c,v 1.13 2001/06/19 10:24:58 brian Exp $
*/
#include <sys/param.h>
@@ -577,9 +577,8 @@ route_UpdateMTU(struct bundle *bundle)
log_Printf(LogTCPIP, "route_UpdateMTU: Netif: %d (%s), dst %s, mtu %d\n",
rtm->rtm_index, Index2Nam(rtm->rtm_index),
inet_ntoa(((struct sockaddr_in *)sa[RTAX_DST])->sin_addr),
- bundle->mtu);
- rt_Update(bundle, in[RTAX_DST]->sin_addr,
- in[RTAX_GATEWAY]->sin_addr);
+ bundle->iface->mtu);
+ rt_Update(bundle, in[RTAX_DST]->sin_addr, in[RTAX_GATEWAY]->sin_addr);
}
}
@@ -890,7 +889,7 @@ rt_Update(struct bundle *bundle, struct in_addr dst, struct in_addr gw)
rtmes.m_rtm.rtm_inits |= RTV_RPIPE;
}
- rtmes.m_rtm.rtm_rmx.rmx_mtu = bundle->mtu;
+ rtmes.m_rtm.rtm_rmx.rmx_mtu = bundle->iface->mtu;
rtmes.m_rtm.rtm_inits |= RTV_MTU;
memset(&rtdata, '\0', sizeof rtdata);
diff --git a/usr.sbin/ppp/ppp/tcp.c b/usr.sbin/ppp/ppp/tcp.c
index ca231142a66..1eafedac274 100644
--- a/usr.sbin/ppp/ppp/tcp.c
+++ b/usr.sbin/ppp/ppp/tcp.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: tcp.c,v 1.10 2001/03/24 01:06:08 brian Exp $
+ * $OpenBSD: tcp.c,v 1.11 2001/06/19 10:24:59 brian Exp $
*/
#include <sys/types.h>
@@ -100,6 +100,7 @@ tcp_OpenConnection(const char *name, char *host, char *port)
static struct device tcpdevice = {
TCP_DEVICE,
"tcp",
+ 0,
{ CD_NOTREQUIRED, 0 },
NULL,
NULL,
diff --git a/usr.sbin/ppp/ppp/tcpmss.c b/usr.sbin/ppp/ppp/tcpmss.c
index ed7ef46b0a1..f8debc8805e 100644
--- a/usr.sbin/ppp/ppp/tcpmss.c
+++ b/usr.sbin/ppp/ppp/tcpmss.c
@@ -28,6 +28,8 @@
#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/route.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
@@ -54,6 +56,7 @@
#include "filter.h"
#include "descriptor.h"
#include "mp.h"
+#include "iface.h"
#ifndef NORADIUS
#include "radius.h"
#endif
@@ -93,7 +96,7 @@ tcpmss_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp,
ntohs(pip->ip_len) == plen && hlen <= plen &&
plen - hlen >= sizeof(struct tcphdr))
MSSFixup((struct tcphdr *)(MBUF_CTOP(bp) + hlen), plen - hlen,
- MAXMSS(bundle->mtu));
+ MAXMSS(bundle->iface->mtu));
return bp;
}
diff --git a/usr.sbin/ppp/ppp/tty.c b/usr.sbin/ppp/ppp/tty.c
index f843a5c5fee..951a1a6248c 100644
--- a/usr.sbin/ppp/ppp/tty.c
+++ b/usr.sbin/ppp/ppp/tty.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: tty.c,v 1.15 2000/11/02 00:54:35 brian Exp $
+ * $OpenBSD: tty.c,v 1.16 2001/06/19 10:25:00 brian Exp $
*/
#include <sys/param.h>
@@ -333,6 +333,7 @@ tty_device2iov(struct device *d, struct iovec *iov, int *niov,
static struct device basettydevice = {
TTY_DEVICE,
"tty",
+ 0,
{ CD_VARIABLE, DEF_TTYCDDELAY },
tty_AwaitCarrier,
NULL,
diff --git a/usr.sbin/ppp/ppp/tun.c b/usr.sbin/ppp/ppp/tun.c
index 896428eaf32..ee4ef0bfb05 100644
--- a/usr.sbin/ppp/ppp/tun.c
+++ b/usr.sbin/ppp/ppp/tun.c
@@ -23,14 +23,16 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: tun.c,v 1.11 2001/03/24 01:06:08 brian Exp $
+ * $OpenBSD: tun.c,v 1.12 2001/06/19 10:25:01 brian Exp $
*/
#include <sys/param.h>
-#ifndef __FreeBSD__
+
#include <sys/socket.h> /* For IFF_ defines */
+#ifndef __FreeBSD__
#include <net/if.h> /* For IFF_ defines */
#endif
+#include <net/route.h>
#include <netinet/in.h>
#include <net/if_types.h>
#include <net/if_tun.h>
@@ -68,6 +70,7 @@
#include "ccp.h"
#include "link.h"
#include "mp.h"
+#include "iface.h"
#ifndef NORADIUS
#include "radius.h"
#endif
@@ -89,7 +92,7 @@ tun_configure(struct bundle *bundle)
}
sprintf(ifr.ifr_name, "tun%d", bundle->unit);
- ifr.ifr_mtu = bundle->mtu;
+ ifr.ifr_mtu = bundle->iface->mtu;
if (ioctl(s, SIOCSIFMTU, &ifr) < 0)
log_Printf(LogERROR, "tun_configure: ioctl(SIOCSIFMTU): %s\n",
strerror(errno));
@@ -100,7 +103,7 @@ tun_configure(struct bundle *bundle)
memset(&info, '\0', sizeof info);
info.type = IFT_PPP;
- info.mtu = bundle->mtu;
+ info.mtu = bundle->iface->mtu;
info.baudrate = bundle->bandwidth;
#ifdef __OpenBSD__
diff --git a/usr.sbin/ppp/ppp/udp.c b/usr.sbin/ppp/ppp/udp.c
index 9d5ce6a5914..cf5a9feb850 100644
--- a/usr.sbin/ppp/ppp/udp.c
+++ b/usr.sbin/ppp/ppp/udp.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: udp.c,v 1.9 2001/03/24 01:06:09 brian Exp $
+ * $OpenBSD: udp.c,v 1.10 2001/06/19 10:25:01 brian Exp $
*/
#include <sys/types.h>
@@ -154,6 +154,7 @@ udp_device2iov(struct device *d, struct iovec *iov, int *niov,
static const struct device baseudpdevice = {
UDP_DEVICE,
"udp",
+ 0,
{ CD_NOTREQUIRED, 0 },
NULL,
NULL,