/*
 * Copyright (C) 2017-2018 Baidu, 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:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * 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.
 *   * Neither the name of Baidu, Inc., nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
 * OWNER 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.
 *
 */

enclave {

    from "sgx_fs.edl" import *;

    struct sockaddr_t
    {
        uint16_t sa_family;
        char     sa_data[14];
    };
    
    trusted {
        /* define ECALLs here. */
    };

    untrusted {

        int u_net_bind_ocall([out] int *error, int sockfd, [in, size=addrlen] const struct sockaddr_t *addr, uint32_t addrlen);
        int u_net_connect_ocall([out] int *error, int sockfd, [in, size=addrlen] const struct sockaddr_t *addr, uint32_t addrlen);
        size_t u_net_recv_ocall([out] int *error, int sockfd, [out, size=len] void *buf, size_t len, int flags);
        size_t u_net_recvfrom_ocall([out] int *error,
                                    int sockfd,
                                    [out, size=len] void *buf,
                                    size_t len,
                                    int flags,
                                    [out, size=_in_addrlen] struct sockaddr_t *src_addr,
                                    uint32_t _in_addrlen,
                                    [in, out] uint32_t *addrlen);
        size_t u_net_send_ocall([out] int *error, int sockfd, [in, size=len] const void *buf, size_t len, int flags);
        size_t u_net_sendto_ocall([out] int *error,
                                  int sockfd,
                                  [in, size=len] const void *buf,
                                  size_t len,
                                  int flags,
                                  [in, size=addrlen] const struct sockaddr_t *dest_addr,
                                  uint32_t addrlen);
        int u_net_getsockopt_ocall([out] int *error,
                                   int sockfd,
                                   int level,
                                   int optname,
                                   [out, size=_in_optlen] void *optval,
                                   uint32_t _in_optlen,
                                   [in, out] uint32_t *optlen);
        int u_net_setsockopt_ocall([out] int *error,
                                   int sockfd,
                                   int level,
                                   int optname,
                                   [in, size=optlen] const void *optval,
                                   uint32_t optlen);
        int u_net_getsockname_ocall([out] int *error,
                                    int sockfd,
                                    [out, size=_in_addrlen] struct sockaddr_t *addr,
                                    uint32_t _in_addrlen,
                                    [in, out] uint32_t *addrlen);
        int u_net_getpeername_ocall([out] int *error,
                                    int sockfd,
                                    [out, size=_in_addrlen] struct sockaddr_t *addr,
                                    uint32_t _in_addrlen,
                                    [in, out] uint32_t *addrlen);
        int u_net_shutdown_ocall([out] int *error, int sockfd, int how);
        int u_net_ioctl_ocall([out] int *error, int fd, int request, [in, out] int *arg);
    };
};