root/usr/src/uts/common/sys/sockfilter.h
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
 */

#ifndef _SYS_SOCKFILTER_H
#define _SYS_SOCKFILTER_H

#include <sys/cred.h>
#include <sys/errno.h>
#include <sys/socket.h>

#ifdef  __cplusplus
extern "C" {
#endif

/*
 * Opaque socket filter handle
 */
typedef struct __sof_handle     *sof_handle_t;

/*
 * Return values for callback functions.
 *
 * A - Attach (passive/active) only
 * P - Passive attach only
 */
typedef enum {
        SOF_RVAL_DEFER = -3,            /* defer notification (P) */
        SOF_RVAL_DETACH = -2,           /* detach filter, continue proc. (A) */
        SOF_RVAL_CONTINUE = -1,         /* continue processing */
        SOF_RVAL_RETURN = 0,            /* stop proc, does not return error */
        SOF_RVAL_EINVAL = EINVAL,       /* stop proc., returns error */
        SOF_RVAL_EACCES = EACCES,       /* stop proc., returns error */
        SOF_RVAL_ENOMEM = ENOMEM,       /* stop proc., returns error */
        SOF_RVAL_ECONNABORTED = ECONNABORTED /* stop proc, returns error */
} sof_rval_t;

/*
 * Events generated by the sofop_notify callback.
 */
typedef enum {                          /* socket ... */
        SOF_EV_CLOSING,                 /* ... is closing */
        SOF_EV_CONNECTED,               /* ... is connected */
        SOF_EV_CONNECTFAILED,           /* ... failed to connect */
        SOF_EV_DISCONNECTED,            /* ... was disconnected */
        SOF_EV_CANTRECVMORE,            /* ... cannot receive any more data */
        SOF_EV_CANTSENDMORE,            /* ... cannot send any more data */
        SOF_EV_INJECT_DATA_IN_OK,       /* ... has cleared rcv flow ctrl */
        SOF_EV_INJECT_DATA_OUT_OK,      /* ... has cleared snd flow ctrl */
} sof_event_t;

/* Filter callbacks */
typedef sof_rval_t      (*sof_attach_active_fn_t)(sof_handle_t, int, int, int,
    cred_t *, void **);
typedef sof_rval_t      (*sof_attach_passive_fn_t)(sof_handle_t, sof_handle_t,
    void *, struct sockaddr *, socklen_t, struct sockaddr *, socklen_t,
    void **);
typedef void            (*sof_detach_fn_t)(sof_handle_t, void *, cred_t *);
typedef mblk_t          *(*sof_data_in_fn_t)(sof_handle_t, void *, mblk_t *,
    int, size_t *);
typedef mblk_t          *(*sof_data_in_proc_fn_t)(sof_handle_t, void *,
    mblk_t *, cred_t *, size_t *);
typedef mblk_t          *(*sof_data_out_fn_t)(sof_handle_t, void *, mblk_t *,
    struct nmsghdr *, cred_t *, sof_rval_t *);
typedef sof_rval_t      (*sof_bind_fn_t)(sof_handle_t, void *,
    struct sockaddr *, socklen_t *, cred_t *);
typedef sof_rval_t      (*sof_listen_fn_t)(sof_handle_t, void *, int *,
    cred_t *);
typedef sof_rval_t      (*sof_accept_fn_t)(sof_handle_t, void *, cred_t *);
typedef sof_rval_t      (*sof_connect_fn_t)(sof_handle_t, void *,
    struct sockaddr *, socklen_t *, cred_t *);
typedef sof_rval_t      (*sof_shutdown_fn_t)(sof_handle_t, void *, int *,
    cred_t *);
typedef sof_rval_t      (*sof_getsockname_fn_t)(sof_handle_t, void *,
    struct sockaddr *, socklen_t *, cred_t *);
typedef sof_rval_t      (*sof_getpeername_fn_t)(sof_handle_t, void *,
    struct sockaddr *, socklen_t *, cred_t *);
typedef sof_rval_t              (*sof_setsockopt_fn_t)(sof_handle_t, void *,
    int, int, void *, socklen_t *, cred_t *);
typedef sof_rval_t      (*sof_getsockopt_fn_t)(sof_handle_t, void *,
    int, int, void *, socklen_t *, cred_t *);
typedef sof_rval_t      (*sof_ioctl_fn_t)(sof_handle_t, void *, int, intptr_t,
    int, int32_t *, cred_t *);
typedef void            (*sof_mblk_prop_fn_t)(sof_handle_t, void *, ssize_t *,
    ushort_t *, ushort_t *);
typedef void            (*sof_notify_fn_t)(sof_handle_t, void *, sof_event_t,
    uintptr_t);

typedef struct sof_ops {
        sof_attach_active_fn_t  sofop_attach_active;
        sof_attach_passive_fn_t sofop_attach_passive;
        sof_detach_fn_t         sofop_detach;
        sof_data_in_fn_t        sofop_data_in;
        sof_data_in_proc_fn_t   sofop_data_in_proc;
        sof_data_out_fn_t       sofop_data_out;
        sof_bind_fn_t           sofop_bind;
        sof_listen_fn_t         sofop_listen;
        sof_connect_fn_t        sofop_connect;
        sof_accept_fn_t         sofop_accept;
        sof_shutdown_fn_t       sofop_shutdown;
        sof_getsockname_fn_t    sofop_getsockname;
        sof_getpeername_fn_t    sofop_getpeername;
        sof_setsockopt_fn_t     sofop_setsockopt;
        sof_getsockopt_fn_t     sofop_getsockopt;
        sof_ioctl_fn_t          sofop_ioctl;
        sof_mblk_prop_fn_t      sofop_mblk_prop;
        sof_notify_fn_t         sofop_notify;
} sof_ops_t;

#define SOF_VERSION     1

extern int      sof_register(int, const char *, const sof_ops_t *, int);
extern int      sof_unregister(const char *);

extern void     sof_newconn_ready(sof_handle_t);
extern void     sof_bypass(sof_handle_t);
extern void     *sof_get_cookie(sof_handle_t);
extern void     *sof_cas_cookie(sof_handle_t, void *, void *);
extern int      sof_inject_data_out(sof_handle_t, mblk_t *, struct nmsghdr *,
    boolean_t *);
extern int      sof_inject_data_in(sof_handle_t, mblk_t *, size_t, int,
    boolean_t *);
extern void     sof_rcv_flowctrl(sof_handle_t, boolean_t);
extern void     sof_snd_flowctrl(sof_handle_t, boolean_t);
extern boolean_t sof_newconn_move(sof_handle_t, sof_handle_t);

#ifdef  __cplusplus
}
#endif

#endif  /* _SYS_SOCKFILTER_H */