53#include <sys/kernel.h>
55#include <sys/malloc.h>
56#include <sys/endian.h>
58#include <sys/sysctl.h>
59#include <sys/syslog.h>
65#include "opt_netgraph.h"
67#if !defined(NETGRAPH_MPPC_COMPRESSION) && !defined(NETGRAPH_MPPC_ENCRYPTION)
69#define NETGRAPH_MPPC_COMPRESSION
70#define NETGRAPH_MPPC_ENCRYPTION
73#error Need either NETGRAPH_MPPC_COMPRESSION or NETGRAPH_MPPC_ENCRYPTION
77#ifdef NG_SEPARATE_MALLOC
80#define M_NETGRAPH_MPPC M_NETGRAPH
83#ifdef NETGRAPH_MPPC_COMPRESSION
86#ifdef NETGRAPH_MPPC_ENCRYPTION
87#include <crypto/rc4/rc4.h>
89#include <crypto/sha1.h>
92#define MPPC_DECOMP_BUFSIZE 8092
93#define MPPC_DECOMP_SAFETY 100
99#define KEYLEN(b) (((b) & MPPE_128) ? 16 : 8)
108#define MPPE_MAX_REKEY 1000
110SYSCTL_NODE(_net_graph, OID_AUTO, mppe, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
114SYSCTL_INT(_net_graph_mppe, OID_AUTO, block_on_max_rekey, CTLFLAG_RWTUN,
118SYSCTL_INT(_net_graph_mppe, OID_AUTO, log_max_rekey, CTLFLAG_RWTUN,
122SYSCTL_INT(_net_graph_mppe, OID_AUTO, max_rekey, CTLFLAG_RWTUN,
123 &
mppe_max_rekey, 0,
"Maximum number of MPPE key re-calculations");
126#define MPPC_FLAG_FLUSHED 0x8000
127#define MPPC_FLAG_RESTART 0x4000
128#define MPPC_FLAG_COMPRESSED 0x2000
129#define MPPC_FLAG_ENCRYPTED 0x1000
130#define MPPC_CCOUNT_MASK 0x0fff
132#define MPPC_CCOUNT_INC(d) ((d) = (((d) + 1) & MPPC_CCOUNT_MASK))
134#define MPPE_UPDATE_MASK 0xff
135#define MPPE_UPDATE_FLAG 0xff
137#define MPPC_COMP_OK 0x05
138#define MPPC_DECOMP_OK 0x05
146#ifdef NETGRAPH_MPPC_COMPRESSION
149#ifdef NETGRAPH_MPPC_ENCRYPTION
151 struct rc4_state rc4;
173 struct mbuf **datap);
175 struct mbuf **datap);
176#ifdef NETGRAPH_MPPC_ENCRYPTION
177static void ng_mppc_getkey(
const u_char *h, u_char *h2,
int len);
178static void ng_mppc_updatekey(u_int32_t bits,
179 u_char *key0, u_char *key,
struct rc4_state *rc4);
196#ifdef NETGRAPH_MPPC_ENCRYPTION
204#define ERROUT(x) do { error = (x); goto done; } while (0)
241 hookPtr = &
priv->xmit.hook;
243 hookPtr = &
priv->recv.hook;
248 if (*hookPtr != NULL)
287#ifndef NETGRAPH_MPPC_COMPRESSION
291#ifndef NETGRAPH_MPPC_ENCRYPTION
305#ifdef NETGRAPH_MPPC_COMPRESSION
307 if (d->history != NULL) {
312 d->history = malloc(isComp ?
313 MPPC_SizeOfCompressionHistory() :
314 MPPC_SizeOfDecompressionHistory(),
316 if (d->history == NULL)
319 MPPC_InitCompressionHistory(d->history);
321 MPPC_InitDecompressionHistory(
327#ifdef NETGRAPH_MPPC_ENCRYPTION
332 bcopy(cfg->
startkey, d->key, keylen);
333 ng_mppc_getkey(cfg->
startkey, d->key, keylen);
338 rc4_init(&d->rc4, d->key, keylen);
380 if (hook ==
priv->xmit.hook) {
381 if (!
priv->xmit.cfg.enable) {
395 if (hook ==
priv->recv.hook) {
396 if (!
priv->recv.cfg.enable) {
403 if (error == EINVAL &&
priv->ctrlnode != 0) {
421 panic(
"%s: unknown hook", __func__);
433#ifdef NETGRAPH_MPPC_COMPRESSION
434 if (
priv->xmit.history != NULL)
436 if (
priv->recv.history != NULL)
456 if (hook ==
priv->xmit.hook)
457 priv->xmit.hook = NULL;
458 if (hook ==
priv->recv.hook)
459 priv->recv.hook = NULL;
482 struct mbuf *m = *datap;
485 m = m_unshare(m, M_NOWAIT);
499#ifdef NETGRAPH_MPPC_COMPRESSION
501 u_short
flags = MPPC_MANDATORY_COMPRESS_FLAGS;
502 u_char *inbuf, *outbuf;
503 int outlen, inlen, ina;
504 u_char *source, *dest;
505 u_long sourceCnt, destCnt;
509 inlen = m->m_pkthdr.len;
510 if (m->m_next == NULL) {
511 inbuf = mtod(m, u_char *);
517 m_copydata(m, 0, inlen, (caddr_t)inbuf);
523 if (outbuf == NULL) {
528 MPPC_InitCompressionHistory(d->history);
539 flags |= MPPC_SAVE_HISTORY;
542 rtn = MPPC_Compress(&source, &dest, &sourceCnt,
543 &destCnt, d->history,
flags, 0);
547 if ((rtn & MPPC_EXPANDED) == 0
551 if ((rtn & MPPC_RESTART_HISTORY) != 0)
555 m_copyback(m, 0, outlen, (caddr_t)outbuf);
556 if (m->m_pkthdr.len < outlen) {
559 }
else if (outlen < m->m_pkthdr.len)
560 m_adj(m, outlen - m->m_pkthdr.len);
562 d->
flushed = (rtn & MPPC_EXPANDED) != 0
563 || (
flags & MPPC_SAVE_HISTORY) == 0;
572 MPPC_InitCompressionHistory(d->history);
581#ifdef NETGRAPH_MPPC_ENCRYPTION
602 rc4_crypt(&d->rc4, mtod(m1, u_char *),
603 mtod(m1, u_char *), m1->m_len);
615 be16enc(mtod(m,
void *),
header);
618 return (*datap == NULL ? ENOBUFS : 0);
632 struct mbuf *m = *datap;
635 m = m_unshare(m, M_NOWAIT);
644 header = be16dec(mtod(m,
void *));
653#ifdef NETGRAPH_MPPC_COMPRESSION
654 if (d->history != NULL)
655 MPPC_InitDecompressionHistory(d->history);
657#ifdef NETGRAPH_MPPC_ENCRYPTION
667 log(LOG_ERR,
"%s: too many (%d) packets"
668 " dropped, disabling node %p!\n",
669 __func__, numLost, node);
671 priv->recv.cfg.enable = 0;
675 log(LOG_ERR,
"%s: %d packets"
676 " dropped, node %p\n",
677 __func__, numLost, node);
684 while (d->
cc != cc) {
709#ifdef NETGRAPH_MPPC_ENCRYPTION
715 log(LOG_ERR,
"%s: rec'd unexpectedly %s packet",
716 __func__,
"encrypted");
720#ifdef NETGRAPH_MPPC_ENCRYPTION
731 rc4_crypt(&d->rc4, mtod(m1, u_char *),
732 mtod(m1, u_char *), m1->m_len);
739 log(LOG_ERR,
"%s: rec'd unexpectedly %s packet",
740 __func__,
"unencrypted");
751 log(LOG_ERR,
"%s: rec'd unexpectedly %s packet",
752 __func__,
"compressed");
758#ifdef NETGRAPH_MPPC_COMPRESSION
761 int flags = MPPC_MANDATORY_DECOMPRESS_FLAGS;
762 u_char *inbuf, *outbuf;
763 int inlen, outlen, ina;
764 u_char *source, *dest;
765 u_long sourceCnt, destCnt;
769 inlen = m->m_pkthdr.len;
770 if (m->m_next == NULL) {
771 inbuf = mtod(m, u_char *);
779 m_copydata(m, 0, inlen, (caddr_t)inbuf);
786 if (outbuf == NULL) {
800 flags |= MPPC_RESTART_HISTORY;
803 rtn = MPPC_Decompress(&source, &dest,
804 &sourceCnt, &destCnt, d->history,
flags);
808 if ((rtn & MPPC_DEST_EXHAUSTED) != 0
810 log(LOG_ERR,
"%s: decomp returned 0x%x",
823 m_copyback(m, 0, outlen, (caddr_t)outbuf);
824 if (m->m_pkthdr.len < outlen) {
827 }
else if (outlen < m->m_pkthdr.len)
828 m_adj(m, outlen - m->m_pkthdr.len);
835 return (*datap == NULL ? ENOBUFS : 0);
847#ifdef NETGRAPH_MPPC_COMPRESSION
848 if (d->history != NULL)
849 MPPC_InitCompressionHistory(d->history);
851#ifdef NETGRAPH_MPPC_ENCRYPTION
858#ifdef NETGRAPH_MPPC_ENCRYPTION
863ng_mppc_getkey(
const u_char *h, u_char *h2,
int len)
865 static const u_char
pad1[40] =
866 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
867 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
868 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
869 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
870 static const u_char
pad2[40] =
871 { 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
872 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
873 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
874 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2 };
879 SHA1Update(&c, h, len);
881 SHA1Update(&c, h2, len);
884 bcopy(hash, h2, len);
891ng_mppc_updatekey(u_int32_t bits,
892 u_char *key0, u_char *key,
struct rc4_state *rc4)
894 const int keylen =
KEYLEN(bits);
896 ng_mppc_getkey(key0, key, keylen);
897 rc4_init(rc4, key, keylen);
898 rc4_crypt(rc4, key, key, keylen);
901 else if ((bits &
MPPE_56) != 0)
903 rc4_init(rc4, key, keylen);
#define NG_HOOK_NODE(hook)
int ng_rcvmsg_t(node_p node, item_p item, hook_p lasthook)
int ng_disconnect_t(hook_p hook)
#define NG_NODE_SET_PRIVATE(node, val)
#define NG_RESPOND_MSG(error, here, item, resp)
#define NG_NODE_IS_VALID(node)
#define NG_NODE_FORCE_WRITER(node)
#define NG_NODE_UNREF(node)
int ng_rmnode_self(node_p here)
#define NG_FWD_NEW_DATA(error, item, hook, m)
#define NG_SEND_MSG_ID(error, here, msg, ID, retaddr)
int ng_rcvdata_t(hook_p hook, item_p item)
int ng_shutdown_t(node_p node)
#define NG_FREE_ITEM(item)
int ng_constructor_t(node_p node)
#define NG_NODE_NUMHOOKS(node)
#define NGI_GET_MSG(i, m)
#define NG_NODE_PRIVATE(node)
int ng_newhook_t(node_p node, hook_p hook, const char *name)
MODULE_DEPEND(ng_ccatm, ngatmbase, 1, 1, 1)
MALLOC_DEFINE(M_NG_CCATM, "ng_ccatm", "netgraph uni api node")
#define NG_MKMESSAGE(msg, cookie, cmdid, len, how)
#define MPPC_DECOMP_SAFETY
static ng_rcvmsg_t ng_mppc_rcvmsg
static void ng_mppc_reset_req(node_p node)
#define MPPC_FLAG_FLUSHED
#define MPPC_CCOUNT_INC(d)
static ng_shutdown_t ng_mppc_shutdown
static ng_constructor_t ng_mppc_constructor
#define MPPC_DECOMP_BUFSIZE
static ng_disconnect_t ng_mppc_disconnect
static int ng_mppc_compress(node_p node, struct mbuf **datap)
static int mppe_max_rekey
SYSCTL_NODE(_net_graph, OID_AUTO, mppe, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "MPPE")
#define MPPC_FLAG_ENCRYPTED
static int mppe_block_on_max_rekey
static struct ng_type ng_mppc_typestruct
NETGRAPH_INIT(mppc, &ng_mppc_typestruct)
#define MPPC_FLAG_COMPRESSED
SYSCTL_INT(_net_graph_mppe, OID_AUTO, block_on_max_rekey, CTLFLAG_RWTUN, &mppe_block_on_max_rekey, 0, "Block node on max MPPE key re-calculations")
static const u_char ng_mppe_weakenkey[3]
#define MPPC_FLAG_RESTART
struct ng_mppc_private * priv_p
static ng_newhook_t ng_mppc_newhook
static int mppe_log_max_rekey
static ng_rcvdata_t ng_mppc_rcvdata
static int ng_mppc_decompress(node_p node, struct mbuf **datap)
#define MPPC_MAX_BLOWUP(n)
#define NG_MPPC_HOOK_DECOMP
#define NG_MPPC_HOOK_COMP
#define NG_MPPC_NODE_TYPE
struct ubt_hci_evhdr header
struct ng_mesg::ng_msghdr header
u_char startkey[MPPE_KEY_LEN]
struct ng_mppc_config cfg