#ifndef _SYS_PROTOSW_H_
#define _SYS_PROTOSW_H_
struct mbuf;
struct ifnet;
struct sockaddr;
struct socket;
struct sockopt;
struct stat;
struct domain;
struct proc;
struct lwp;
struct pr_usrreqs;
struct protosw {
int pr_type;
struct domain *pr_domain;
short pr_protocol;
short pr_flags;
void (*pr_input)
(struct mbuf *, int, int);
void *(*pr_ctlinput)
(int, const struct sockaddr *, void *);
int (*pr_ctloutput)
(int, struct socket *, struct sockopt *);
const struct pr_usrreqs *pr_usrreqs;
void (*pr_init)
(void);
void (*pr_fasttimo)
(void);
void (*pr_slowtimo)
(void);
void (*pr_drain)
(void);
};
#define PR_SLOWHZ 2
#define PR_FASTHZ 5
#define PR_ATOMIC 0x01
#define PR_ADDR 0x02
#define PR_CONNREQUIRED 0x04
#define PR_WANTRCVD 0x08
#define PR_RIGHTS 0x10
#define PR_LISTEN 0x20
#define PR_LASTHDR 0x40
#define PR_ABRTACPTDIS 0x80
#define PR_PURGEIF 0x100
#define PR_ADDR_OPT 0x200
#define PRU_ATTACH 0
#define PRU_DETACH 1
#define PRU_BIND 2
#define PRU_LISTEN 3
#define PRU_CONNECT 4
#define PRU_ACCEPT 5
#define PRU_DISCONNECT 6
#define PRU_SHUTDOWN 7
#define PRU_RCVD 8
#define PRU_SEND 9
#define PRU_ABORT 10
#define PRU_CONTROL 11
#define PRU_SENSE 12
#define PRU_RCVOOB 13
#define PRU_SENDOOB 14
#define PRU_SOCKADDR 15
#define PRU_PEERADDR 16
#define PRU_CONNECT2 17
#define PRU_FASTTIMO 18
#define PRU_SLOWTIMO 19
#define PRU_PROTORCV 20
#define PRU_PROTOSEND 21
#define PRU_PURGEIF 22
#define PRU_NREQ 23
#ifdef PRUREQUESTS
static const char * const prurequests[] = {
"ATTACH", "DETACH", "BIND", "LISTEN",
"CONNECT", "ACCEPT", "DISCONNECT", "SHUTDOWN",
"RCVD", "SEND", "ABORT", "CONTROL",
"SENSE", "RCVOOB", "SENDOOB", "SOCKADDR",
"PEERADDR", "CONNECT2", "FASTTIMO", "SLOWTIMO",
"PROTORCV", "PROTOSEND", "PURGEIF",
};
#endif
#define PRC_IFDOWN 0
#define PRC_ROUTEDEAD 1
#define PRC_QUENCH2 3
#define PRC_QUENCH 4
#define PRC_MSGSIZE 5
#define PRC_HOSTDEAD 6
#define PRC_HOSTUNREACH 7
#define PRC_UNREACH_NET 8
#define PRC_UNREACH_HOST 9
#define PRC_UNREACH_PROTOCOL 10
#define PRC_UNREACH_PORT 11
#define PRC_UNREACH_SRCFAIL 13
#define PRC_REDIRECT_NET 14
#define PRC_REDIRECT_HOST 15
#define PRC_REDIRECT_TOSNET 16
#define PRC_REDIRECT_TOSHOST 17
#define PRC_TIMXCEED_INTRANS 18
#define PRC_TIMXCEED_REASS 19
#define PRC_PARAMPROB 20
#define PRC_NCMDS 21
#define PRC_IS_REDIRECT(cmd) \
((cmd) >= PRC_REDIRECT_NET && (cmd) <= PRC_REDIRECT_TOSHOST)
#ifdef PRCREQUESTS
static const char * const prcrequests[] = {
"IFDOWN", "ROUTEDEAD", "#2", "DEC-BIT-QUENCH2",
"QUENCH", "MSGSIZE", "HOSTDEAD", "#7",
"NET-UNREACH", "HOST-UNREACH", "PROTO-UNREACH", "PORT-UNREACH",
"#12", "SRCFAIL-UNREACH", "NET-REDIRECT", "HOST-REDIRECT",
"TOSNET-REDIRECT", "TOSHOST-REDIRECT", "TX-INTRANS", "TX-REASS",
"PARAMPROB"
};
#endif
#define PRCO_GETOPT 0
#define PRCO_SETOPT 1
#define PRCO_NCMDS 2
#ifdef PRCOREQUESTS
static const char * const prcorequests[] = {
"GETOPT", "SETOPT",
};
#endif
#ifdef _KERNEL
struct pr_usrreqs {
int (*pr_attach)(struct socket *, int);
void (*pr_detach)(struct socket *);
int (*pr_accept)(struct socket *, struct sockaddr *);
int (*pr_connect)(struct socket *, struct sockaddr *, struct lwp *);
int (*pr_connect2)(struct socket *, struct socket *);
int (*pr_bind)(struct socket *, struct sockaddr *, struct lwp *);
int (*pr_listen)(struct socket *, struct lwp *);
int (*pr_disconnect)(struct socket *);
int (*pr_shutdown)(struct socket *);
int (*pr_abort)(struct socket *);
int (*pr_ioctl)(struct socket *, u_long, void *, struct ifnet *);
int (*pr_stat)(struct socket *, struct stat *);
int (*pr_peeraddr)(struct socket *, struct sockaddr *);
int (*pr_sockaddr)(struct socket *, struct sockaddr *);
int (*pr_rcvd)(struct socket *, int, struct lwp *);
int (*pr_recvoob)(struct socket *, struct mbuf *, int);
int (*pr_send)(struct socket *, struct mbuf *, struct sockaddr *,
struct mbuf *, struct lwp *);
int (*pr_sendoob)(struct socket *, struct mbuf *, struct mbuf *);
int (*pr_purgeif)(struct socket *, struct ifnet *);
};
extern u_int pfslowtimo_now;
extern u_int pffasttimo_now;
#define PRT_SLOW_ARM(t, nticks) (t) = (pfslowtimo_now + (nticks))
#define PRT_FAST_ARM(t, nticks) (t) = (pffasttimo_now + (nticks))
#define PRT_SLOW_DISARM(t) (t) = 0
#define PRT_FAST_DISARM(t) (t) = 0
#define PRT_SLOW_ISARMED(t) ((t) != 0)
#define PRT_FAST_ISARMED(t) ((t) != 0)
#define PRT_SLOW_ISEXPIRED(t) (PRT_SLOW_ISARMED((t)) && (t) <= pfslowtimo_now)
#define PRT_FAST_ISEXPIRED(t) (PRT_FAST_ISARMED((t)) && (t) <= pffasttimo_now)
struct sockaddr;
const struct protosw *pffindproto(int, int, int);
const struct protosw *pffindtype(int, int);
struct domain *pffinddomain(int);
void pfctlinput(int, const struct sockaddr *);
void pfctlinput2(int, const struct sockaddr *, void *);
#include <sys/systm.h>
#define PR_WRAP_USRREQS(name) \
static int \
name##_attach_wrapper(struct socket *a, int b) \
{ \
int rv; \
KERNEL_LOCK(1, NULL); \
rv = name##_attach(a, b); \
KERNEL_UNLOCK_ONE(NULL); \
return rv; \
} \
static void \
name##_detach_wrapper(struct socket *a) \
{ \
KERNEL_LOCK(1, NULL); \
name##_detach(a); \
KERNEL_UNLOCK_ONE(NULL); \
} \
static int \
name##_accept_wrapper(struct socket *a, \
struct sockaddr *b) \
{ \
int rv; \
KERNEL_LOCK(1, NULL); \
rv = name##_accept(a, b); \
KERNEL_UNLOCK_ONE(NULL); \
return rv; \
} \
static int \
name##_bind_wrapper(struct socket *a, \
struct sockaddr *b, struct lwp *c) \
{ \
int rv; \
KERNEL_LOCK(1, NULL); \
rv = name##_bind(a, b, c); \
KERNEL_UNLOCK_ONE(NULL); \
return rv; \
} \
static int \
name##_connect_wrapper(struct socket *a, \
struct sockaddr *b, struct lwp *c) \
{ \
int rv; \
KERNEL_LOCK(1, NULL); \
rv = name##_connect(a, b, c); \
KERNEL_UNLOCK_ONE(NULL); \
return rv; \
} \
static int \
name##_connect2_wrapper(struct socket *a, \
struct socket *b) \
{ \
int rv; \
KERNEL_LOCK(1, NULL); \
rv = name##_connect2(a, b); \
KERNEL_UNLOCK_ONE(NULL); \
return rv; \
} \
static int \
name##_listen_wrapper(struct socket *a, struct lwp *b) \
{ \
int rv; \
KERNEL_LOCK(1, NULL); \
rv = name##_listen(a, b); \
KERNEL_UNLOCK_ONE(NULL); \
return rv; \
} \
static int \
name##_disconnect_wrapper(struct socket *a) \
{ \
int rv; \
KERNEL_LOCK(1, NULL); \
rv = name##_disconnect(a); \
KERNEL_UNLOCK_ONE(NULL); \
return rv; \
} \
static int \
name##_shutdown_wrapper(struct socket *a) \
{ \
int rv; \
KERNEL_LOCK(1, NULL); \
rv = name##_shutdown(a); \
KERNEL_UNLOCK_ONE(NULL); \
return rv; \
} \
static int \
name##_abort_wrapper(struct socket *a) \
{ \
int rv; \
KERNEL_LOCK(1, NULL); \
rv = name##_abort(a); \
KERNEL_UNLOCK_ONE(NULL); \
return rv; \
} \
static int \
name##_ioctl_wrapper(struct socket *a, u_long b, \
void *c, struct ifnet *d) \
{ \
int rv; \
KERNEL_LOCK(1, NULL); \
rv = name##_ioctl(a, b, c, d); \
KERNEL_UNLOCK_ONE(NULL); \
return rv; \
} \
static int \
name##_stat_wrapper(struct socket *a, struct stat *b) \
{ \
int rv; \
KERNEL_LOCK(1, NULL); \
rv = name##_stat(a, b); \
KERNEL_UNLOCK_ONE(NULL); \
return rv; \
} \
static int \
name##_peeraddr_wrapper(struct socket *a, \
struct sockaddr *b) \
{ \
int rv; \
KERNEL_LOCK(1, NULL); \
rv = name##_peeraddr(a, b); \
KERNEL_UNLOCK_ONE(NULL); \
return rv; \
} \
static int \
name##_sockaddr_wrapper(struct socket *a, \
struct sockaddr *b) \
{ \
int rv; \
KERNEL_LOCK(1, NULL); \
rv = name##_sockaddr(a, b); \
KERNEL_UNLOCK_ONE(NULL); \
return rv; \
} \
static int \
name##_rcvd_wrapper(struct socket *a, int b, \
struct lwp *c) \
{ \
int rv; \
KERNEL_LOCK(1, NULL); \
rv = name##_rcvd(a, b, c); \
KERNEL_UNLOCK_ONE(NULL); \
return rv; \
} \
static int \
name##_recvoob_wrapper(struct socket *a, \
struct mbuf *b, int c) \
{ \
int rv; \
KERNEL_LOCK(1, NULL); \
rv = name##_recvoob(a, b, c); \
KERNEL_UNLOCK_ONE(NULL); \
return rv; \
} \
static int \
name##_send_wrapper(struct socket *a, struct mbuf *b, \
struct sockaddr *c, struct mbuf *d, struct lwp *e) \
{ \
int rv; \
KERNEL_LOCK(1, NULL); \
rv = name##_send(a, b, c, d, e); \
KERNEL_UNLOCK_ONE(NULL); \
return rv; \
} \
static int \
name##_sendoob_wrapper(struct socket *a, \
struct mbuf *b, struct mbuf *c) \
{ \
int rv; \
KERNEL_LOCK(1, NULL); \
rv = name##_sendoob(a, b, c); \
KERNEL_UNLOCK_ONE(NULL); \
return rv; \
} \
static int \
name##_purgeif_wrapper(struct socket *a, \
struct ifnet *b) \
{ \
int rv; \
KERNEL_LOCK(1, NULL); \
rv = name##_purgeif(a, b); \
KERNEL_UNLOCK_ONE(NULL); \
return rv; \
}
#define PR_WRAP_CTLOUTPUT(name) \
static int \
name##_wrapper(int a, struct socket *b, \
struct sockopt *c) \
{ \
int rv; \
KERNEL_LOCK(1, NULL); \
rv = name(a, b, c); \
KERNEL_UNLOCK_ONE(NULL); \
return rv; \
}
#define PR_WRAP_CTLINPUT(name) \
static void * \
name##_wrapper(int a, const struct sockaddr *b, void *c)\
{ \
void *rv; \
KERNEL_LOCK(1, NULL); \
rv = name(a, b, c); \
KERNEL_UNLOCK_ONE(NULL); \
return rv; \
}
#include <sys/socketvar.h>
#define PR_WRAP_INPUT(name) \
static void \
name##_wrapper(struct mbuf *m, int off, int proto) \
{ \
mutex_enter(softnet_lock); \
name(m, off, proto); \
mutex_exit(softnet_lock); \
}
#endif
#endif