version 1.187, 2020/03/06 10:26:59 |
version 1.187.2.8, 2020/04/11 08:11:58 |
Line 92 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 92 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <net/if_sppp.h> |
#include <net/if_sppp.h> |
#include <net/if_spppvar.h> |
#include <net/if_spppvar.h> |
|
|
|
#ifndef _NET_IF_STATS_H_ |
|
#define if_statadd(ifp,member,amount) do { (ifp)->member+=(amount); } while (0) |
|
#define if_statadd2(ifp,m1,a1,m2,a2) do { if_statadd(ifp,m1,a1); if_statadd(ifp,m2,a2);} while(0) |
|
#define if_statinc(ifp,member) if_statadd(ifp,member,1) |
|
#endif |
|
|
#ifdef NET_MPSAFE |
#ifdef NET_MPSAFE |
#define SPPPSUBR_MPSAFE 1 |
#define SPPPSUBR_MPSAFE 1 |
#endif |
#endif |
Line 146 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 152 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#define LCP_OPT_RESERVED 6 /* reserved */ |
#define LCP_OPT_RESERVED 6 /* reserved */ |
#define LCP_OPT_PROTO_COMP 7 /* protocol field compression */ |
#define LCP_OPT_PROTO_COMP 7 /* protocol field compression */ |
#define LCP_OPT_ADDR_COMP 8 /* address/control field compression */ |
#define LCP_OPT_ADDR_COMP 8 /* address/control field compression */ |
|
#define LCP_OPT_FCS_ALTS 9 /* FCS alternatives */ |
|
#define LCP_OPT_SELF_DESC_PAD 10 /* self-describing padding */ |
|
#define LCP_OPT_CALL_BACK 13 /* callback */ |
|
#define LCP_OPT_COMPOUND_FRMS 15 /* compound frames */ |
|
#define LCP_OPT_MP_MRRU 17 /* multilink MRRU */ |
|
#define LCP_OPT_MP_SSNHF 18 /* multilink short seq. numbers */ |
|
#define LCP_OPT_MP_EID 19 /* multilink endpoint discriminator */ |
|
|
#define IPCP_OPT_ADDRESSES 1 /* both IP addresses; deprecated */ |
#define IPCP_OPT_ADDRESSES 1 /* both IP addresses; deprecated */ |
#define IPCP_OPT_COMPRESSION 2 /* IP compression protocol */ |
#define IPCP_OPT_COMPRESSION 2 /* IP compression protocol */ |
Line 329 static void sppp_lcp_scr(struct sppp *sp |
|
Line 342 static void sppp_lcp_scr(struct sppp *sp |
|
static void sppp_lcp_check_and_close(struct sppp *sp); |
static void sppp_lcp_check_and_close(struct sppp *sp); |
static int sppp_ncp_check(struct sppp *sp); |
static int sppp_ncp_check(struct sppp *sp); |
|
|
|
static struct mbuf *sppp_ml_defrag(struct sppp *sp, struct mbuf *m, |
|
u_int16_t *protocolp); |
|
|
static void sppp_ipcp_init(struct sppp *sp); |
static void sppp_ipcp_init(struct sppp *sp); |
static void sppp_ipcp_up(struct sppp *sp); |
static void sppp_ipcp_up(struct sppp *sp); |
static void sppp_ipcp_down(struct sppp *sp); |
static void sppp_ipcp_down(struct sppp *sp); |
Line 510 sppp_change_phase(struct sppp *sp, int p |
|
Line 526 sppp_change_phase(struct sppp *sp, int p |
|
} |
} |
} |
} |
|
|
|
|
|
/* |
|
* Defragment an MP packet. |
|
* |
|
* Returns NULL or an assembled packet or the original, |
|
* and adjusts the passed protocol to the inner one. |
|
* |
|
* Called with and returns a packet without PPP header, |
|
* but with MP fragment header. |
|
* |
|
* Called and returns with lock held. |
|
*/ |
|
static struct mbuf * |
|
sppp_ml_defrag(struct sppp *sp, struct mbuf *m, u_int16_t *protocolp) |
|
{ |
|
u_int8_t *p; |
|
u_int8_t flags; |
|
u_int32_t seqid; |
|
u_int16_t protocol; |
|
int newflen; |
|
|
|
if (*protocolp != PPP_MP) |
|
return m; /* not ours */ |
|
|
|
if (sp->lcp.mrru == 0) |
|
return m; /* |
|
* ours, but we're not ready. |
|
* sppp_input will arrange for rejection. |
|
*/ |
|
|
|
if (m->m_len < 4) { |
|
m = m_pullup(m, 4); |
|
if (m == NULL) { |
|
if_statadd2(&sp->pp_if, if_ierrors, 1, if_iqdrops, 1); |
|
return NULL; |
|
} |
|
} |
|
p = mtod(m, u_int8_t *); |
|
flags = *p; |
|
seqid = (p[1]<<16) + (p[2]<<8) + p[3]; |
|
|
|
m_adj(m, 4); |
|
|
|
/* We're manipulating the defragmentation state below: */ |
|
SPPP_UPGRADE(sp); |
|
|
|
if (flags & 0x80) { |
|
/* Beginning fragment. */ |
|
sp->lcp.ml_seq_xpctd=seqid+1; /* next expected */ |
|
|
|
/* TODO: if prefix, count dropped? */ |
|
|
|
m_freem(sp->lcp.ml_prefix); |
|
sp->lcp.ml_prefix = m; |
|
|
|
} else if (seqid == sp->lcp.ml_seq_xpctd) { |
|
sp->lcp.ml_seq_xpctd=seqid+1; /* next expected */ |
|
if (sp->lcp.ml_prefix == 0) { |
|
/* didn't see B frame. */ |
|
/* TODO: count as dropped. */ |
|
m_freem(m); |
|
return NULL; |
|
} |
|
/* |
|
* m_cat might free the first mbuf (with pkthdr) |
|
* in 2nd chain; therefore: |
|
*/ |
|
newflen = m->m_pkthdr.len; |
|
m_cat(sp->lcp.ml_prefix, m); |
|
sp->lcp.ml_prefix->m_pkthdr.len += newflen; |
|
|
|
} else { |
|
/* |
|
* sequence error. |
|
* |
|
* For now, only drop this fragment, and don't touch state- |
|
* might be from the long past or future, and we could still |
|
* finish our current prefix. |
|
* |
|
* TODO: count as dropped. |
|
*/ |
|
m_freem(sp->lcp.ml_prefix); |
|
return NULL; |
|
} |
|
/* Successfully got the Beginning or appended a non-B packet.*/ |
|
if (flags & 0x40) { |
|
/* B/next was E packet. Unwrap gift and deliver. */ |
|
m = sp->lcp.ml_prefix; |
|
sp->lcp.ml_prefix = NULL; |
|
|
|
if (m->m_len < 2) { |
|
m = m_pullup(m,2); |
|
if (m == NULL) { |
|
/* TODO: count as dropped. */ |
|
return NULL; |
|
} |
|
} |
|
/* RFC 1990 2.: don't assume no protocol field compression */ |
|
p = mtod(m, u_int8_t *); |
|
protocol = *p; |
|
|
|
if (protocol & 1) { |
|
m_adj(m, 1); |
|
} else { |
|
protocol = (protocol << 8) + p[1]; |
|
m_adj(m, 2); |
|
} |
|
*protocolp = protocol; |
|
|
|
return m; |
|
} |
|
|
|
return NULL; |
|
} |
|
|
|
|
/* |
/* |
* Exported functions, comprising our interface to the lower layer. |
* Exported functions, comprising our interface to the lower layer. |
*/ |
*/ |
Line 620 sppp_input(struct ifnet *ifp, struct mbu |
|
Line 752 sppp_input(struct ifnet *ifp, struct mbu |
|
protocol = ntohs(h->protocol); |
protocol = ntohs(h->protocol); |
} |
} |
|
|
|
m = sppp_ml_defrag(sp, m, &protocol); |
|
if (m == 0) { |
|
SPPP_UNLOCK(sp); |
|
return; |
|
} |
|
|
switch (protocol) { |
switch (protocol) { |
default: |
default: |
if (sp->state[IDX_LCP] == STATE_OPENED) { |
if (sp->state[IDX_LCP] == STATE_OPENED) { |
Line 2215 sppp_lcp_up(struct sppp *sp) |
|
Line 2353 sppp_lcp_up(struct sppp *sp) |
|
/* Initialize activity timestamp: opening a connection is an activity */ |
/* Initialize activity timestamp: opening a connection is an activity */ |
sp->pp_last_receive = sp->pp_last_activity = time_uptime; |
sp->pp_last_receive = sp->pp_last_activity = time_uptime; |
|
|
|
/* Initialize mlppp state */ |
|
sp->lcp.mrru = sp->lcp.their_mrru = 0; |
|
sp->lcp.ml_prefix = NULL; |
|
sp->lcp.ml_seq_xpctd = 0; |
|
|
/* |
/* |
* If this interface is passive or dial-on-demand, and we are |
* If this interface is passive or dial-on-demand, and we are |
* still in Initial state, it means we've got an incoming |
* still in Initial state, it means we've got an incoming |
Line 2374 sppp_lcp_RCR(struct sppp *sp, struct lcp |
|
Line 2517 sppp_lcp_RCR(struct sppp *sp, struct lcp |
|
if (debug) |
if (debug) |
addlog(" [invalid]"); |
addlog(" [invalid]"); |
break; |
break; |
|
case LCP_OPT_MP_EID: |
|
if (len >= l && l >= 3) { |
|
switch (p[2]) { |
|
case 0: if (l==3+ 0) continue;break; |
|
case 2: if (l==3+ 4) continue;break; |
|
case 3: if (l==3+ 6) continue;break; |
|
case 6: if (l==3+16) continue;break; |
|
case 1: /* FALLTHROUGH */ |
|
case 4: if (l<=3+20) continue;break; |
|
case 5: if (l<=3+15) continue;break; |
|
/* XXX should it be default: continue;? */ |
|
} |
|
} |
|
if (debug) |
|
addlog(" [invalid class %d len %d]", p[2], l); |
|
break; |
|
case LCP_OPT_MP_SSNHF: |
|
if (len >= 2 && l == 2) { |
|
if (debug) |
|
addlog(" [rej]"); |
|
break; |
|
} |
|
if (debug) |
|
addlog(" [invalid]"); |
|
break; |
|
case LCP_OPT_MP_MRRU: |
|
/* Multilink maximum received reconstructed unit */ |
|
/* should be fall through, both are same length */ |
|
/* FALLTHROUGH */ |
case LCP_OPT_MRU: |
case LCP_OPT_MRU: |
/* Maximum receive unit. */ |
/* Maximum receive unit. */ |
if (len >= 4 && l == 4) |
if (len >= 4 && l == 4) |
Line 2532 sppp_lcp_RCR(struct sppp *sp, struct lcp |
|
Line 2704 sppp_lcp_RCR(struct sppp *sp, struct lcp |
|
break; |
break; |
} |
} |
continue; |
continue; |
|
case LCP_OPT_MP_EID: |
|
/* |
|
* Endpoint identification. |
|
* Always agreeable, |
|
* but ignored by now. |
|
*/ |
|
if (debug) { |
|
addlog(" class %d", p[2]); |
|
sppp_print_bytes(p+3, p[1]-3); |
|
} |
|
continue; |
|
case LCP_OPT_MP_MRRU: |
|
/* |
|
* Maximum received reconstructed unit. |
|
* Always agreeable, |
|
* but ignored by now. |
|
*/ |
|
sp->lcp.their_mrru = p[2] * 256 + p[3]; |
|
if (debug) |
|
addlog(" %ld", sp->lcp.their_mrru); |
|
continue; |
} |
} |
if (rlen + l > blen) { |
if (rlen + l > blen) { |
if (debug) |
if (debug) |
Line 6016 sppp_lcp_opt_name(u_char opt) |
|
Line 6209 sppp_lcp_opt_name(u_char opt) |
|
case LCP_OPT_MAGIC: return "magic"; |
case LCP_OPT_MAGIC: return "magic"; |
case LCP_OPT_PROTO_COMP: return "proto-comp"; |
case LCP_OPT_PROTO_COMP: return "proto-comp"; |
case LCP_OPT_ADDR_COMP: return "addr-comp"; |
case LCP_OPT_ADDR_COMP: return "addr-comp"; |
|
case LCP_OPT_SELF_DESC_PAD: return "sdpad"; |
|
case LCP_OPT_CALL_BACK: return "callback"; |
|
case LCP_OPT_COMPOUND_FRMS: return "cmpd-frms"; |
|
case LCP_OPT_MP_MRRU: return "mrru"; |
|
case LCP_OPT_MP_SSNHF: return "mp-ssnhf"; |
|
case LCP_OPT_MP_EID: return "mp-eid"; |
} |
} |
snprintf(buf, sizeof(buf), "0x%x", opt); |
snprintf(buf, sizeof(buf), "0x%x", opt); |
return buf; |
return buf; |