#ifndef _NETIPSEC_IPSEC_H_
#define _NETIPSEC_IPSEC_H_
#if defined(_KERNEL_OPT)
#include "opt_inet.h"
#include "opt_ipsec.h"
#endif
#include <net/pfkeyv2.h>
#ifdef _KERNEL
#include <sys/socketvar.h>
#include <sys/localcount.h>
#include <netinet/in_pcb.h>
#include <netipsec/keydb.h>
struct secpolicyindex {
u_int8_t dir;
union sockaddr_union src;
union sockaddr_union dst;
u_int8_t prefs;
u_int8_t prefd;
u_int16_t ul_proto;
};
struct secpolicy {
struct pslist_entry pslist_entry;
struct localcount localcount;
struct secpolicyindex spidx;
u_int32_t id;
u_int state;
#define IPSEC_SPSTATE_DEAD 0
#define IPSEC_SPSTATE_ALIVE 1
u_int origin;
#define IPSEC_SPORIGIN_USER 0
#define IPSEC_SPORIGIN_KERNEL 1
u_int policy;
struct ipsecrequest *req;
time_t created;
time_t lastused;
time_t lifetime;
time_t validtime;
};
struct ipsecrequest {
struct ipsecrequest *next;
struct secasindex saidx;
u_int level;
struct secpolicy *sp;
};
struct inpcbpolicy {
struct secpolicy *sp_in;
struct secpolicy *sp_out;
int priv;
struct {
struct secpolicy *cachesp;
struct secpolicyindex cacheidx;
int cachehint;
#define IPSEC_PCBHINT_UNKNOWN 0
#define IPSEC_PCBHINT_YES 1
#define IPSEC_PCBHINT_NO 2
u_int cachegen;
} sp_cache[3];
int sp_cacheflags;
#define IPSEC_PCBSP_CONNECTED 1
struct inpcb *sp_inp;
};
extern u_int ipsec_spdgen;
static __inline bool
ipsec_pcb_skip_ipsec(struct inpcbpolicy *pcbsp, int dir)
{
KASSERT(inp_locked(pcbsp->sp_inp));
return pcbsp->sp_cache[(dir)].cachehint == IPSEC_PCBHINT_NO &&
pcbsp->sp_cache[(dir)].cachegen == ipsec_spdgen;
}
struct secspacq {
LIST_ENTRY(secspacq) chain;
struct secpolicyindex spidx;
time_t created;
int count;
};
#endif
#define IPSEC_ADDRSTRLEN (INET6_ADDRSTRLEN + 11)
#define IPSEC_LOGSASTRLEN 192
#define IPSEC_PORT_ANY 0
#define IPSEC_ULPROTO_ANY 255
#define IPSEC_PROTO_ANY 255
#define IPSEC_MODE_ANY 0
#define IPSEC_MODE_TRANSPORT 1
#define IPSEC_MODE_TUNNEL 2
#define IPSEC_MODE_TCPMD5 3
#define IPSEC_DIR_ANY 0
#define IPSEC_DIR_INBOUND 1
#define IPSEC_DIR_OUTBOUND 2
#define IPSEC_DIR_MAX 3
#define IPSEC_DIR_INVALID 4
#define IPSEC_DIR_IS_VALID(dir) ((dir) >= 0 && (dir) <= IPSEC_DIR_MAX)
#define IPSEC_DIR_IS_INOROUT(dir) ((dir) == IPSEC_DIR_INBOUND || \
(dir) == IPSEC_DIR_OUTBOUND)
#define IPSEC_POLICY_DISCARD 0
#define IPSEC_POLICY_NONE 1
#define IPSEC_POLICY_IPSEC 2
#define IPSEC_POLICY_ENTRUST 3
#define IPSEC_POLICY_BYPASS 4
#define IPSEC_LEVEL_DEFAULT 0
#define IPSEC_LEVEL_USE 1
#define IPSEC_LEVEL_REQUIRE 2
#define IPSEC_LEVEL_UNIQUE 3
#define IPSEC_MANUAL_REQID_MAX 0x3fff
#define IPSEC_REPLAYWSIZE 32
#ifdef _KERNEL
extern int ipsec_debug;
#ifdef IPSEC_DEBUG
extern int ipsec_replay;
extern int ipsec_integrity;
#endif
extern struct secpolicy ip4_def_policy;
extern int ip4_esp_trans_deflev;
extern int ip4_esp_net_deflev;
extern int ip4_ah_trans_deflev;
extern int ip4_ah_net_deflev;
extern int ip4_ah_cleartos;
extern int ip4_ah_offsetmask;
extern int ip4_ipsec_dfbit;
extern int ip4_ipsec_ecn;
extern int crypto_support;
#include <sys/syslog.h>
#define DPRINTF(fmt, args...) \
do { \
if (ipsec_debug) \
log(LOG_DEBUG, "%s: " fmt, __func__, ##args); \
} while (0)
#define IPSECLOG(level, fmt, args...) \
do { \
if (ipsec_debug) \
log(level, "%s: " fmt, __func__, ##args); \
} while (0)
#define ipsec_indone(m) \
((m->m_flags & M_AUTHIPHDR) || (m->m_flags & M_DECRYPTED))
#define ipsec_outdone(m) \
(m_tag_find((m), PACKET_TAG_IPSEC_OUT_DONE) != NULL)
static __inline bool
ipsec_skip_pfil(struct mbuf *m)
{
bool rv;
if (ipsec_indone(m) &&
((m->m_pkthdr.pkthdr_flags & PKTHDR_FLAG_IPSEC_SKIP_PFIL) != 0)) {
m->m_pkthdr.pkthdr_flags &= ~PKTHDR_FLAG_IPSEC_SKIP_PFIL;
rv = true;
} else {
rv = false;
}
return rv;
}
void ipsec_pcbconn(struct inpcbpolicy *);
void ipsec_pcbdisconn(struct inpcbpolicy *);
void ipsec_invalpcbcacheall(void);
struct inpcb;
int ipsec4_output(struct mbuf *, struct inpcb *, int, u_long *, bool *, bool *, bool *);
int ipsec_ip_input_checkpolicy(struct mbuf *, bool);
void ipsec_mtu(struct mbuf *, int *);
#ifdef INET6
void ipsec6_udp_cksum(struct mbuf *);
#endif
struct inpcb;
int ipsec_init_pcbpolicy(struct socket *so, struct inpcbpolicy **);
int ipsec_copy_policy(const struct inpcbpolicy *, struct inpcbpolicy *);
u_int ipsec_get_reqlevel(const struct ipsecrequest *);
int ipsec_set_policy(struct inpcb *, const void *, size_t, kauth_cred_t);
int ipsec_get_policy(struct inpcb *, const void *, size_t, struct mbuf **);
int ipsec_delete_pcbpolicy(struct inpcb *);
int ipsec_in_reject(struct mbuf *, struct inpcb *);
struct secasvar *ipsec_lookup_sa(const struct ipsecrequest *,
const struct mbuf *);
struct secas;
struct tcpcb;
int ipsec_chkreplay(u_int32_t, const struct secasvar *);
int ipsec_updatereplay(u_int32_t, const struct secasvar *);
size_t ipsec_hdrsiz(struct mbuf *, u_int, struct inpcb *);
size_t ipsec4_hdrsiz_tcp(struct tcpcb *);
union sockaddr_union;
const char *ipsec_address(const union sockaddr_union* sa, char *, size_t);
const char *ipsec_logsastr(const struct secasvar *, char *, size_t);
void *esp4_ctlinput(int, const struct sockaddr *, void *);
void *ah4_ctlinput(int, const struct sockaddr *, void *);
void ipsec_output_init(void);
struct m_tag;
void ipsec4_common_input(struct mbuf *m, int, int);
int ipsec4_common_input_cb(struct mbuf *, struct secasvar *, int, int);
int ipsec4_process_packet(struct mbuf *, const struct ipsecrequest *, u_long *);
int ipsec_process_done(struct mbuf *, const struct ipsecrequest *,
struct secasvar *, int);
struct mbuf *m_clone(struct mbuf *);
struct mbuf *m_makespace(struct mbuf *, int, int, int *);
void *m_pad(struct mbuf *, int);
int m_striphdr(struct mbuf *, int, int);
extern int ipsec_used __read_mostly;
extern int ipsec_enabled __read_mostly;
#endif
#ifndef _KERNEL
char *ipsec_set_policy(const char *, int);
int ipsec_get_policylen(char *);
char *ipsec_dump_policy(char *, const char *);
const char *ipsec_strerror(void);
#endif
#ifdef _KERNEL
void ah_attach(void);
void esp_attach(void);
void ipcomp_attach(void);
void ipe4_attach(void);
void tcpsignature_attach(void);
void ipsec_attach(void);
void sysctl_net_inet_ipsec_setup(struct sysctllog **);
#ifdef INET6
void sysctl_net_inet6_ipsec6_setup(struct sysctllog **);
#endif
#endif
#endif