#ifndef KPI_MBUF_H
#include <sys/kpi_mbuf.h>
#endif

#ifndef SYS_CONTROL_H
#include <sys/kern_control.h>
#endif

#ifndef KPI_SOCKETFILTER_H
#include <sys/kpi_socketfilter.h>
#endif

#include <sys/event.h>
#include <sys/vnode.h>
#include <sys/attr.h>

int NewFileFilterYDUPP(int a){};
int NewDlgHookYDUPP(int a){};
int NewModalFilterYDUPP(int a){};
int  *_NSGetArgc(){};
char * _NSGetArgv();

/*mbuf_freem

void mbuf_freem(
    mbuf_t mbuf);  
Parameters
mbuf
The first mbuf in the chain to free.
Discussion 

Frees a chain of mbufs link through mnext.*/
void mbuf_freem(
    mbuf_t mbuf){
//TODO
};  


/*mbuf_setnext

errno_t mbuf_setnext(
    mbuf_t mbuf,
    mbuf_t next);  
Parameters
mbuf
The mbuf.
next
The new next mbuf.
Return Value

0 upon success otherwise the errno error. 
Discussion 

Sets the next mbuf in the chain.*/
errno_t mbuf_setnext(
    mbuf_t mbuf,
    mbuf_t next){
//TODO
};  


/*mbuf_setnextpkt

void mbuf_setnextpkt(
    mbuf_t mbuf,
    mbuf_t nextpkt);  
Parameters
mbuf
The mbuf.
nextpkt
The new next packet.
Discussion 

Sets the next packet attached to this mbuf.*/
void mbuf_setnextpkt(
    mbuf_t mbuf,
    mbuf_t nextpkt){
//TODO
};  


/*mbuf_nextpkt

mbuf_t mbuf_nextpkt(
    mbuf_t mbuf);  
Parameters
mbuf
The mbuf.
Return Value

The nextpkt. 
Discussion 

Gets the next packet from the mbuf.*/
mbuf_t mbuf_nextpkt(
    mbuf_t mbuf){
//TODO
};  


/*mbuf_pkthdr_setlen

void mbuf_pkthdr_setlen(
    mbuf_t mbuf,
    size_t len);  
Parameters
mbuf
The mbuf containing the packet header.
len
The new length of the packet.
Return Value

0 upon success otherwise the errno error. 
Discussion 

Sets the length of the packet in the packet header.*/

void mbuf_pkthdr_setlen(
    mbuf_t mbuf,
    size_t len){
//TODO
};  


/*mbuf_setlen

void mbuf_setlen(
    mbuf_t mbuf,
    size_t len);  
Parameters
mbuf
The mbuf.
len
The new length.
Return Value

0 upon success otherwise the errno error. 
Discussion 

Sets the length of data in this packet. Be careful to not set the length over the space available in the mbuf.*/
void mbuf_setlen(
    mbuf_t mbuf,
    size_t len){
//TODO
};  


/*mbuf_pkthdr_setrcvif

errno_t mbuf_pkthdr_setrcvif(
    mbuf_t mbuf,
    ifnet_t ifnet);  
Parameters
mbuf
The mbuf containing the packet header.
ifnet
A reference to an interface.
Return Value

0 upon success otherwise the errno error. 
Discussion 

Sets the interface the packet was received on.*/
errno_t mbuf_pkthdr_setrcvif(
    mbuf_t mbuf,
    ifnet_t ifnet){
//TODO
};  

/*mbuf_tag_find

errno_t mbuf_tag_find(
    mbuf_t mbuf,
    mbuf_tag_id_t module_id, 
    mbuf_tag_type_t type,
    size_t *length,
    void** data_p);  
Parameters
mbuf
The mbuf the tag is attached to.
module_id
A module identifier returned by mbuf_tag_id_find.
type
The 16 bit type of the tag to find.
length
Upon success, the length of data will be store in *length.
data_p
Upon successful return, *data_p will point to the buffer allocated for the mtag.
Return Value

0 upon success otherwise the errno error. 
Discussion 

Find the data associated with an mbuf tag.*/
errno_t mbuf_tag_find(
    mbuf_t mbuf,
    mbuf_tag_id_t module_id, 
    mbuf_tag_type_t type,
    size_t *length,
    void** data_p){
//TODO
};  


/*mbuf_tag_allocate

errno_t mbuf_tag_allocate(
    mbuf_t mbuf,
    mbuf_tag_id_t module_id, 
    mbuf_tag_type_t type,
    size_t length, 
    mbuf_how_t how,
    void** data_p);  
Parameters
mbuf
The mbuf to attach this tag to.
module_id
A module identifier returned by mbuf_tag_id_find.
type
A 16 bit type value. For a given module_id, you can use a number of different tag types.
length
The length, in bytes, to allocate for storage that will be associated with this tag on this mbuf.
how
Indicate whether you want to block and wait for memory if memory is not immediately available.
data_p
Upon successful return, *data_p will point to the buffer allocated for the mtag.
Return Value

0 upon success otherwise the errno error. 
Discussion 

Allocate an mbuf tag. Mbuf tags allow various portions of the stack to tag mbufs with data that will travel with the mbuf through the stack. 

Tags may only be added to mbufs with packet headers (MBUF_PKTHDR flag is set). Mbuf tags are freed when the mbuf is freed or when mbuf_tag_free is called.*/
errno_t mbuf_tag_allocate(
    mbuf_t mbuf,
    mbuf_tag_id_t module_id, 
    mbuf_tag_type_t type,
    size_t length, 
    mbuf_how_t how,
    void** data_p){
//TODO
};  


/*mbuf_flags

mbuf_flags_t mbuf_flags(
    mbuf_t mbuf);  
Parameters
mbuf
The mbuf.
Return Value

The flags. 
Discussion 

Returns the set flags.*/
mbuf_flags_t mbuf_flags(
    mbuf_t mbuf){
//TODO
};  


/*mbuf_len

size_t mbuf_len(
    mbuf_t mbuf);  
Parameters
mbuf
The mbuf.
Return Value

The length. 
Discussion 

Gets the length of data in this mbuf.*/
size_t mbuf_len(
    mbuf_t mbuf){
//TODO
};  


/*mbuf_next

mbuf_t mbuf_next(
    mbuf_t mbuf);  
Parameters
mbuf
The mbuf.
Return Value

The next mbuf in the chain. 
Discussion 

Returns the next mbuf in the chain.*/
mbuf_t mbuf_next(
    mbuf_t mbuf){
//TODO
};  


/*mbuf_gethdr

errno_t mbuf_gethdr(
    mbuf_how_t how,
    mbuf_type_t type,
    mbuf_t*mbuf);  
Parameters
how
Blocking or non-blocking.
type
The type of the mbuf.
mbuf
The mbuf.
Return Value

0 on success, errno error on failure. 
Discussion 

Allocates an mbuf without a cluster for external data. Sets a flag to indicate there is a packet header and initializes the packet header.*/
errno_t mbuf_gethdr(
    mbuf_how_t how,
    mbuf_type_t type,
    mbuf_t*mbuf){
//TODO
};  



/*mbuf_pkthdr_len

size_t mbuf_pkthdr_len(
    mbuf_t mbuf);  
Parameters
mbuf
The mbuf containing the packet header with the length to be changed.
Return Value

The length, in bytes, of the packet. 
Discussion 

Returns the length as reported by the packet header.*/
size_t mbuf_pkthdr_len(
    mbuf_t mbuf){
//TODO
};  


/*ctl_enqueuedata

errno_t ctl_enqueuedata(
    kern_ctl_ref kctlref,
    u_int32_t unit,
    void *data,
    size_t len,
    u_int32_t flags);  
Parameters
kctlref
The control reference of the kernel control.
unit
The unit number of the kernel control instance.
data
A pointer to the data to send.
len
The length of data to send.
flags
Send flags. CTL_DATA_NOWAKEUP and CTL_DATA_EOR are currently the only supported flags.
Return Value

0 - Data was enqueued to be read by the client. EINVAL - Invalid parameters. EMSGSIZE - The buffer is too large. ENOBUFS - The queue is full or there are no free mbufs. 
Discussion 

Send data from the kernel control to the client.*/
errno_t ctl_enqueuedata(
    kern_ctl_ref kctlref,
    u_int32_t unit,
    void *data,
    size_t len,
    u_int32_t flags){
//TODO
};  

/*sock_inject_data_in

errno_t sock_inject_data_in(
    socket_t so,
    const struct sockaddr*from, 
    mbuf_t data,
    mbuf_t control,
    sflt_data_flag_t flags);  
Parameters
so
The socket to inject the data on.
from
The address the data is from, only necessary on un-connected sockets. A copy of the address will be made, caller is responsible for freeing the address after calling this function.
data
The data and possibly control mbufs.
control
The separate control mbufs.
flags
Flags indicating the type of data.
Return Value

0 on success otherwise the errno error. If the function returns an error, the caller is responsible for freeing the mbuf. 
Discussion 

Inject data in to the receive buffer of the socket as if it had come from the network.*/
errno_t sock_inject_data_in(
    socket_t so,
    const struct sockaddr *from,
    mbuf_t data,
    mbuf_t control,
    sflt_data_flag_t flags){
//TODO
};

/*sock_inject_data_out

errno_t sock_inject_data_out(
    socket_t so,
    const struct sockaddr*to, 
    mbuf_t data,
    mbuf_t control,
    sflt_data_flag_t flags);  
Parameters
so
The socket to inject the data on.
to
The address the data should be sent to, only necessary on un-connected sockets. The caller is responsible for freeing the to address after sock_inject_data_out returns.
data
The data and possibly control mbufs.
control
The separate control mbufs.
flags
Flags indicating the type of data.
Return Value

0 on success otherwise the errno error. The data and control values are always freed regardless of return value. 
Discussion 

Inject data in to the send buffer of the socket as if it had come from the client.*/
 errno_t sock_inject_data_out(
    socket_t so,
    const struct sockaddr *to,
    mbuf_t data,
    mbuf_t control,
    sflt_data_flag_t flags){
//TODO
}; 

/*void microtime(struct timeval *tv);

Declared In: <sys/time.h>

Dependency: com.apple.kernel.bsd

This function returns a timeval struct containing the current wall clock time*/

void microtime(struct timeval *tv){
//TODO
};

/*sock_getsockname

errno_t sock_getsockname(
    socket_t so,
    struct sockaddr *sockname,
    int socknamelen);  
Parameters
so
The socket.
sockname
Storage for the local name.
socknamelen
Length of storage for the socket name.
Return Value

0 on success otherwise the errno error. 
Discussion 

Retrieves the local address of a socket. See 'man 2 getsockname'.*/
errno_t sock_getsockname(
    socket_t so,
    struct sockaddr *sockname,
    int socknamelen){
//TODO
};  

 int proc_selfpid(){
//TODO
};

int kauth_getuid(){
//TODO
};


/*ctl_deregister

errno_t ctl_deregister(
    kern_ctl_ref kctlref);  
Parameters
kctlref
The control reference of the control to unregister.
Return Value

0 - Kernel control was unregistered. EINVAL - The kernel control reference was invalid. EBUSY - The kernel control has clients still attached. 
Discussion 

Unregister a kernel control. A kernel extension must unregister it's kernel control(s) before unloading. If a kernel control has clients attached, this call will fail.*/
errno_t ctl_deregister(
    kern_ctl_ref kctlref){
//TODO
};  


/*Using msleep

In addition to Mach and I/O Kit routines, BSD provides msleep, which is the recommended way to delay in the BSD portions of the kernel. In other parts of the kernel, you should with either use wait_queue functions or use assert_wait and thread_wakeup functions, both of which are closely tied to the Mach scheduler, and are described in “Kernel Thread APIs”.

The msleep call is similar to a condition variable. It puts a thread to sleep until wakeup or wakeup_one is called on that channel. Unlike a condition variable, however, you can set a timeout measured in clock ticks. This means that it is both a synchronization call and a delay. The prototypes follow:msleep(void *channel, lck_mtx_t *mtx, int priority, const char *wmesg,  struct  timespec *timeout);
msleep0(vvoid *channel, lck_mtx_t *mtx, int priority, const char  *wmesg, uint64_t  deadline);
wakeup(void *channel);
wakeup_one(void *channel);*/
void wakeup(void *channel){
//TODO
};

int bsd_timeout(int a,int b,int c){
//TODO
};

int msleep(int a,int b,int c,int d, int e){
//TODO
};


/*mbuf_tag_id_find

errno_t mbuf_tag_id_find(
    const char *module_string, 
    mbuf_tag_id_t *module_id);  
Parameters
module_string
A unique string identifying your module. Example: com.apple.nke.SharedIP.
module_id
Upon return, a unique identifier for use with mbuf_tag_* functions. This identifier is valid until the machine is rebooted.
Return Value

0 upon success otherwise the errno error. 
Discussion 

Lookup the module id for a string. If there is no module id assigned to this string, a new module id will be assigned. The string should be the bundle id of the kext. In the case of a tag that will be shared across multiple kexts, a common bundle id style string should be used. 

The lookup operation is not optimized. A module should call this function once during startup and chache the module id. The module id will not be resassigned until the machine reboots.*/
errno_t mbuf_tag_id_find(
    const char *module_string, 
    mbuf_tag_id_t *module_id){
//TODO
};  


/*sflt_register

errno_t sflt_register(
    const struct sflt_filter *filter,
    int domain, 
    int type,
    int protocol);  
Parameters
filter
A structure describing the filter.
domain
The protocol domain these filters will be attached to.
type
The socket type these filters will be attached to.
protocol
The protocol these filters will be attached to.
Return Value

0 on success otherwise the errno error. 
Discussion 

Registers a socket filter. See 'man 2 socket' for a desciption of domain, type, and protocol.*/
errno_t sflt_register(
    const struct sflt_filter *filter,
    int domain, 
    int type,
    int protocol){
//TODO
};  


/*sflt_unregister

errno_t sflt_unregister(
    sflt_handle handle);  
Parameters
handle
The sf_handle of the socket filter to unregister.
Return Value

0 on success otherwise the errno error. 
Discussion 

Unregisters a socket filter. This will not detach the socket filter from all sockets it may be attached to at the time, it will just prevent the socket filter from being attached to any new sockets.*/
errno_t sflt_unregister(
    sflt_handle handle){
//TODO
};  


/*ctl_register

errno_t ctl_register(
    struct kern_ctl_reg *userkctl,
    kern_ctl_ref *kctlref);  
Parameters
userkctl
A structure defining the kernel control to be attached. Each callback is optional.
kctlref
Upon successful return, the kctlref will contain a reference to the attached kernel control. This reference is used to unregister the kernel control. This reference will also be passed in to the callbacks each time they are called.
Return Value

0 - Kernel control was registered. EINVAL - The registration structure was not valid. ENOMEM - There was insufficient memory. EEXIST - A controller with that id/unit is already registered. 
Discussion 

Register a kernel control. This will enable clients to connect to the kernel control using a PF_SYSTEM socket.*/
errno_t ctl_register(
    struct kern_ctl_reg *userkctl,
    kern_ctl_ref *kctlref){
//TODO
};  
  float roundf(float x){
//TODO
};


//func
 /*int
     kqueue(void);

     int
     kevent(int kq, const struct kevent *changelist, int nchanges,
         struct kevent *eventlist, int nevents,
         const struct timespec *timeout);*/

int     kqueue(void){};
int    kevent(int kq, const struct kevent *changelist, int nchanges,
         struct kevent *eventlist, int nevents,
         const struct timespec *timeout){};




/*SIGSETOPS(3)             BSD Library Functions Manual             SIGSETOPS(3)

NAME
     sigemptyset, sigfillset, sigaddset, sigdelset, sigismember -- manipulate
     signal sets

LIBRARY
     Standard C Library (libc, -lc)

SYNOPSIS
     #include <signal.h>

     int
     sigemptyset(sigset_t *set);

     int
     sigfillset(sigset_t *set);

     int
     sigaddset(sigset_t *set, int signo);

     int
     sigdelset(sigset_t *set, int signo);

     int
     sigismember(const sigset_t *set, int signo);

DESCRIPTION
     These functions manipulate signal sets stored in a sigset_t.  Either
     sigemptyset() or sigfillset() must be called for every object of type
     sigset_t before any other use of the object.

     The sigemptyset() function initializes a signal set to be empty.

     The sigfillset() function initializes a signal set to contain all sig-signals.
     nals.

     The sigaddset() function adds the specified signal signo to the signal
     set.

     The sigdelset() function deletes the specified signal signo from the sig-signal
     nal set.

     The sigismember() function returns whether a specified signal signo is
     contained in the signal set.

     These functions are provided as macros in the include file <signal.h>.
     Actual functions are available if their names are undefined (with #undef
     name).

RETURN VALUES
     The sigismember() function returns 1 if the signal is a member of the
     set, 0 otherwise.  The other functions return 0.

ERRORS
     Currently no errors are detected.

SEE ALSO
     kill(2), sigaction(2), sigsuspend(2)

STANDARDS
     These functions are defined by IEEE Std 1003.1-1988 (``POSIX.1'').

BSD                              June 4, 1993                              BSD*/

     int
     sigemptyset(sigset_t *set){};

     int
     sigfillset(sigset_t *set){};

     int
     sigaddset(sigset_t *set, int signo){};

     int
     sigdelset(sigset_t *set, int signo){};

     int
     sigismember(const sigset_t *set, int signo){};


