summaryrefslogtreecommitdiff
path: root/sys/net/pipex_local.h
diff options
context:
space:
mode:
authorYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2010-01-11 03:50:57 +0000
committerYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2010-01-11 03:50:57 +0000
commit07b6c47bf3506b1d17f7c5d0a4996c64403ffe9d (patch)
treeea4224e3fe2f8a4cbf4fc9276d2aee2660988032 /sys/net/pipex_local.h
parent944b7335f573c141a17ea60164543855f70a2e2e (diff)
Initial import PIPEX. PIPEX(Pppac IP EXtension) is a IP forwarding
acceleration for PPP access concentrator. ok mcbride@ dlg@ deraadt@ reyk@.
Diffstat (limited to 'sys/net/pipex_local.h')
-rw-r--r--sys/net/pipex_local.h319
1 files changed, 319 insertions, 0 deletions
diff --git a/sys/net/pipex_local.h b/sys/net/pipex_local.h
new file mode 100644
index 00000000000..9f5b4cc3c3a
--- /dev/null
+++ b/sys/net/pipex_local.h
@@ -0,0 +1,319 @@
+/* $Id: pipex_local.h,v 1.1 2010/01/11 03:50:56 yasuoka Exp $ */
+/*
+ * Copyright (c) 2009 Internet Initiative Japan Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#define PIPEX_PPTP 1
+#define PIPEX_PPPOE 1
+#define PIPEX_MPPE 1
+
+#define PIPEX_ENABLED 0x0001
+
+#ifndef LOG_PPPAC
+#define LOG_PPPAC LOG_KERN
+#endif
+
+/* compile time option constants */
+#ifndef PIPEX_MAX_SESSION
+#define PIPEX_MAX_SESSION 512
+#endif
+#ifdef NBSAFE_RC4
+#define PIPEX_RC4_CTXLEN 288
+#else
+#define PIPEX_RC4_CTXLEN 1152
+#endif
+#define PIPEX_HASH_DIV 8
+#define PIPEX_HASH_SIZE (PIPEX_MAX_SESSION/PIPEX_HASH_DIV)
+#define PIPEX_HASH_MASK (PIPEX_HASH_SIZE-1)
+#define PIPEX_CLOSE_TIMEOUT 30
+#define PIPEX_DEQUEUE_LIMIT (IFQ_MAXLEN >> 1)
+#define PIPEX_PPPMINLEN 5
+ /* minimum PPP header length is 1 and minimum ppp payload length is 4 */
+
+#ifndef NNBY /* usually defined on the <sys/types.h> */
+#define NNBY 8 /* number of bits of a byte */
+#endif
+
+#ifdef PIPEX_MPPE
+/* mppe rc4 key */
+struct pipex_mppe {
+ int16_t stateless:1, /* key change mode */
+ resetreq:1,
+ reserved:14;
+ int16_t keylenbits; /* key length */
+ int16_t keylen;
+ uint16_t coher_cnt; /* cohency counter */
+ struct {
+ u_char rc4ctx_space[PIPEX_RC4_CTXLEN]; /* space for rc4ctx */
+ } rc4ctx; /* rc4ctx */
+ u_char master_key[PIPEX_MPPE_KEYLEN]; /* master key of MPPE */
+ u_char session_key[PIPEX_MPPE_KEYLEN]; /* session key of MPPE */
+};
+#endif /* PIPEX_MPPE */
+
+#ifdef PIPEX_PPPOE
+struct pipex_pppoe_session {
+ struct ifnet *over_ifp; /* ether inteface */
+ struct sockaddr peer_addr; /* peer's sockaddr */
+};
+#endif /* PIPEX_PPPOE */
+
+#ifdef PIPEX_PPTP
+struct pipex_pptp_session {
+ /* sequence number gap between pipex and userland */
+ int32_t snd_gap; /* gap of our sequence */
+ int32_t rcv_gap; /* gap of peer's sequence */
+ int32_t ul_snd_una; /* userland send acked seq */
+
+ uint32_t snd_nxt; /* send next */
+ uint32_t rcv_nxt; /* receive next */
+ uint32_t snd_una; /* send acked sequence */
+ uint32_t rcv_acked; /* recv acked sequence */
+
+ int winsz; /* windows size */
+ int maxwinsz; /* max windows size */
+ int peer_maxwinsz; /* peer's max windows size */
+
+ struct in_addr peer_address; /* inet destination address */
+ struct in_addr our_address; /* inet source address */
+};
+#endif /* PIPEX_PPTP */
+
+/* pppac ip-extension sessoin table */
+struct pipex_session {
+ struct radix_node ps4_rn[2]; /* tree glue, and other values */
+ LIST_ENTRY(pipex_session) session_list; /* all session chain */
+ LIST_ENTRY(pipex_session) state_list; /* state list chain */
+ LIST_ENTRY(pipex_session) id_chain; /* id hash chain */
+ LIST_ENTRY(pipex_session) peer_addr_chain;
+ /* peer's address hash chain */
+ uint16_t state; /* pipex session state */
+#define PIPEX_STATE_INITIAL 0x0000
+#define PIPEX_STATE_OPENED 0x0001
+#define PIPEX_STATE_CLOSE_WAIT 0x0002
+#define PIPEX_STATE_CLOSED 0x0003
+
+ uint16_t ip_forward:1, /* {en|dis}ableIP forwarding */
+ is_multicast:1, /* virtual entry for mutlicast */
+ reserved:14;
+ uint16_t protocol; /* tunnel protocol (PK) */
+ uint16_t session_id; /* session-id (PK) */
+ uint16_t peer_session_id; /* peer's session-id */
+ uint16_t peer_mru; /* peer's MRU */
+ uint32_t timeout_sec; /* idle timeout */
+ int ppp_id; /* PPP id */
+
+ struct sockaddr_in ip_address; /* remote address (AK) */
+ struct sockaddr_in ip_netmask; /* remote address mask (AK) */
+
+ struct pipex_iface_context* pipex_iface;/* context for interface */
+
+ uint32_t ppp_flags; /* configure flags */
+#ifdef PIPEX_MPPE
+ int ccp_id; /* CCP packet id */
+ struct pipex_mppe
+ mppe_recv, /* MPPE context for incoming */
+ mppe_send; /* MPPE context for outgoing */
+#endif /*PIPEXMPPE */
+ struct pipex_statistics stat; /* statistics */
+ union {
+#ifdef PIPEX_PPPOE
+ struct pipex_pppoe_session pppoe; /* context for PPPoE */
+#endif /* PIPEX_PPPOE */
+#ifdef PIPEX_PPTP
+ struct pipex_pptp_session pptp; /* context for PPTP */
+#endif /* PIPEX_PPTP */
+ char _proto_unknown[0];
+ } proto;
+};
+
+/* gre header */
+struct pipex_gre_header {
+ uint16_t flags; /* flags and version*/
+#define PIPEX_GRE_KFLAG 0x2000 /* keys present */
+#define PIPEX_GRE_SFLAG 0x1000 /* seq present */
+#define PIPEX_GRE_AFLAG 0x0080 /* ack present */
+#define PIPEX_GRE_VER 0x0001 /* gre version code */
+#define PIPEX_GRE_VERMASK 0x0003 /* gre version mask */
+
+ uint16_t type;
+#define PIPEX_GRE_PROTO_PPP 0x880b /* gre/ppp */
+
+ uint16_t len; /* length not include gre header */
+ uint16_t call_id; /* call_id */
+} __attribute__((__packed__));
+
+/* ppp/ccp header */
+struct pipex_ccp_header {
+ uint8_t code;
+ uint8_t id;
+ uint16_t len;
+} __attribute__((__packed__));
+
+/* ppp header */
+struct pipex_ppp_header {
+ uint8_t c[0]; /* ppp proto */
+ uint16_t code; /* ppp proto (2 oct) */
+} __attribute__((__packed__));
+
+
+/* pppoe header */
+struct pipex_pppoe_header {
+ uint8_t vertype; /* version and type */
+#define PIPEX_PPPOE_VERTYPE 0x11 /* version and type code */
+
+ uint8_t code; /* code */
+#define PIPEX_PPPOE_CODE_SESSION 0x00 /* code session */
+
+ uint16_t session_id; /* session id */
+ uint16_t length; /* length */
+} __attribute__((__packed__));
+
+#ifdef PIPEX_DEBUG
+#define PIPEX_DBG(a) if (pipex_debug & 1) pipex_session_log a
+/* #define PIPEX_MPPE_DBG(a) if (pipex_debug & 1) pipex_session_log a */
+#define PIPEX_MPPE_DBG(a)
+#else
+#define PIPEX_DBG(a)
+#define PIPEX_MPPE_DBG(a)
+#endif /* PIPEX_DEBUG */
+
+#define PIPEX_ID_HASHTABLE(key) \
+ (&pipex_id_hashtable[(key) & PIPEX_HASH_MASK])
+#define PIPEX_PEER_ADDR_HASHTABLE(key) \
+ (&pipex_peer_addr_hashtable[ntohl((key)) & PIPEX_HASH_MASK])
+#define PIPEX_ADDR_HASHTABLE(key) \
+ (&pipex_addr_hashtable[ntohl((key)) & PIPEX_HASH_MASK])
+
+#define GETCHAR(c, cp) { (c) = *(cp)++; }
+#define PUTCHAR(s, cp) { *(cp)++ = (u_char) (s); }
+#define GETSHORT(s, cp) { \
+ (s) = *(cp)++ << 8; \
+ (s) |= *(cp)++; \
+}
+#define PUTSHORT(s, cp) { \
+ *(cp)++ = (u_char) ((s) >> 8); \
+ *(cp)++ = (u_char) (s); \
+}
+#define GETLONG(l, cp) { \
+ (l) = *(cp)++ << 8; \
+ (l) |= *(cp)++; (l) <<= 8; \
+ (l) |= *(cp)++; (l) <<= 8; \
+ (l) |= *(cp)++; \
+}
+#define PUTLONG(l, cp) { \
+ *(cp)++ = (u_char) ((l) >> 24); \
+ *(cp)++ = (u_char) ((l) >> 16); \
+ *(cp)++ = (u_char) ((l) >> 8); \
+ *(cp)++ = (u_char) (l); \
+}
+#define PIPEX_PULLUP(m0, l) \
+ if ((m0)->m_len < (l)) { \
+ if ((m0)->m_pkthdr.len < (l)) { \
+ PIPEX_DBG((NULL, LOG_DEBUG, \
+ "<%s> received packet is too short.", \
+ __func__)); \
+ m_freem(m0); \
+ (m0) = NULL; \
+ } else { \
+ (m0) = m_pullup((m0), (l)); \
+ KASSERT((m0) != NULL); \
+ } \
+ }
+#define PIPEX_SEEK_NEXTHDR(ptr, len, t) \
+ ((t) (((char *)ptr) + len))
+#define SEQ32_LT(a,b) ((int)((a) - (b)) < 0)
+#define SEQ32_LE(a,b) ((int)((a) - (b)) <= 0)
+#define SEQ32_GT(a,b) ((int)((a) - (b)) > 0)
+#define SEQ32_GE(a,b) ((int)((a) - (b)) >= 0)
+#define SEQ32_SUB(a,b) ((int32_t)((a) - (b)))
+
+#define RUPDIV(n,d) (((n) + (d) - ((n) % (d))) / (d))
+#define pipex_session_is_acfc_accepted(s) \
+ (((s)->ppp_flags & PIPEX_PPP_ACFC_ACCEPTED)? 1 : 0)
+#define pipex_session_is_pfc_accepted(s) \
+ (((s)->ppp_flags & PIPEX_PPP_PFC_ACCEPTED)? 1 : 0)
+#define pipex_session_is_acfc_enabled(s) \
+ (((s)->ppp_flags & PIPEX_PPP_ACFC_ENABLED)? 1 : 0)
+#define pipex_session_is_pfc_enabled(s) \
+ (((s)->ppp_flags & PIPEX_PPP_PFC_ENABLED)? 1 : 0)
+#define pipex_session_has_acf(s) \
+ (((s)->ppp_flags & PIPEX_PPP_HAS_ACF)? 1 : 0)
+#define pipex_session_is_mppe_accepted(s) \
+ (((s)->ppp_flags & PIPEX_PPP_MPPE_ACCEPTED)? 1 : 0)
+#define pipex_session_is_mppe_enabled(s) \
+ (((s)->ppp_flags & PIPEX_PPP_MPPE_ENABLED)? 1 : 0)
+#define pipex_session_is_mppe_required(s) \
+ (((s)->ppp_flags & PIPEX_PPP_MPPE_REQUIRED)? 1 : 0)
+#define pipex_mppe_rc4_keybits(r) ((r)->keylen << 3)
+#define PIPEX_IPGRE_HDRLEN (sizeof(struct ip) + sizeof(struct pipex_gre_header))
+#define PIPEX_TCP_OPTLEN 40
+
+/*
+ * static function prototypes
+ */
+static int pipex_add_session (struct pipex_session_req *, struct pipex_iface_context *);
+static int pipex_close_session (struct pipex_session_close_req *);
+static int pipex_config_session (struct pipex_session_config_req *);
+static int pipex_get_stat (struct pipex_session_stat_req *);
+static int pipex_get_closed (struct pipex_session_list_req *);
+static int pipex_destroy_session (struct pipex_session *);
+static struct pipex_session *pipex_lookup_by_ip_address (struct in_addr);
+static struct pipex_session *pipex_lookup_by_session_id (int, int);
+static void pipex_ppp_output (struct mbuf *, struct pipex_session *, int);
+static inline int pipex_ppp_proto (struct mbuf *, struct pipex_session *, int, int *);
+static void pipex_ppp_input (struct mbuf *, struct pipex_session *, int);
+static void pipex_ip_input (struct mbuf *, struct pipex_session *);
+
+#ifdef PIPEX_PPPOE
+static void pipex_pppoe_output (struct mbuf *, struct pipex_session *);
+#endif
+
+#ifdef PIPEX_PPTP
+static void pipex_pptp_output (struct mbuf *, struct pipex_session *, int, int);
+#endif
+
+#ifdef PIPEX_MPPE
+static void pipex_mppe_req_init (struct pipex_mppe_req *, struct pipex_mppe *);
+static void GetNewKeyFromSHA (u_char *, u_char *, int, u_char *);
+static inline int rc4_key (struct pipex_mppe *, int, u_char *);
+static inline void rc4 (struct pipex_mppe *, int, u_char *, u_char *);
+static int rc4_key (struct pipex_mppe *, int, u_char *);
+static void rc4 (struct pipex_mppe *, int, u_char *, u_char *);
+static void pipex_mppe_reduce_key (struct pipex_mppe *);
+static void mppe_key_change (struct pipex_mppe *);
+static void pipex_mppe_input (struct mbuf *, struct pipex_session *);
+static void pipex_mppe_output (struct mbuf *, struct pipex_session *);
+static void pipex_ccp_input (struct mbuf *, struct pipex_session *);
+static int pipex_ccp_output (struct pipex_session *, int, int);
+#endif
+
+static struct mbuf *adjust_tcp_mss (struct mbuf *, int);
+static struct mbuf *ip_is_idle_packet (struct mbuf *, int *);
+static void pipex_session_log (struct pipex_session *, int, const char *, ...) __attribute__((__format__(__printf__,3,4)));
+static int pipex_ppp_enqueue (struct mbuf *, struct pipex_session *, struct ifqueue *);
+static void pipex_ppp_dequeue (void);
+static void pipex_timer_start (void);
+static void pipex_timer_stop (void);
+static void pipex_timer (void *);