#include #include #include #define debug 0 // Virtual address at which to receive page mappings containing client requests. #define REQVA 0x0ffff000 union Nsipc nsipcbuf __attribute__((aligned(PGSIZE))); // Send an IP request to the network server, and wait for a reply. // The request body should be in nsipcbuf, and parts of the response // may be written back to nsipcbuf. // type: request code, passed as the simple integer IPC value. // Returns 0 if successful, < 0 on failure. static int nsipc(unsigned type) { static envid_t nsenv; if (nsenv == 0) nsenv = ipc_find_env(ENV_TYPE_NS); static_assert(sizeof(nsipcbuf) == PGSIZE); if (debug) cprintf("[%08x] nsipc %d\n", thisenv->env_id, type); ipc_send(nsenv, type, &nsipcbuf, PTE_P|PTE_W|PTE_U); return ipc_recv(NULL, NULL, NULL); } int nsipc_accept(int s, struct sockaddr *addr, socklen_t *addrlen) { int r; nsipcbuf.accept.req_s = s; nsipcbuf.accept.req_addrlen = *addrlen; if ((r = nsipc(NSREQ_ACCEPT)) >= 0) { struct Nsret_accept *ret = &nsipcbuf.acceptRet; memmove(addr, &ret->ret_addr, ret->ret_addrlen); *addrlen = ret->ret_addrlen; } return r; } int nsipc_bind(int s, struct sockaddr *name, socklen_t namelen) { nsipcbuf.bind.req_s = s; memmove(&nsipcbuf.bind.req_name, name, namelen); nsipcbuf.bind.req_namelen = namelen; return nsipc(NSREQ_BIND); } int nsipc_shutdown(int s, int how) { nsipcbuf.shutdown.req_s = s; nsipcbuf.shutdown.req_how = how; return nsipc(NSREQ_SHUTDOWN); } int nsipc_close(int s) { nsipcbuf.close.req_s = s; return nsipc(NSREQ_CLOSE); } int nsipc_connect(int s, const struct sockaddr *name, socklen_t namelen) { nsipcbuf.connect.req_s = s; memmove(&nsipcbuf.connect.req_name, name, namelen); nsipcbuf.connect.req_namelen = namelen; return nsipc(NSREQ_CONNECT); } int nsipc_listen(int s, int backlog) { nsipcbuf.listen.req_s = s; nsipcbuf.listen.req_backlog = backlog; return nsipc(NSREQ_LISTEN); } int nsipc_recv(int s, void *mem, int len, unsigned int flags) { int r; nsipcbuf.recv.req_s = s; nsipcbuf.recv.req_len = len; nsipcbuf.recv.req_flags = flags; if ((r = nsipc(NSREQ_RECV)) >= 0) { assert(r < 1600 && r <= len); memmove(mem, nsipcbuf.recvRet.ret_buf, r); } return r; } int nsipc_send(int s, const void *buf, int size, unsigned int flags) { nsipcbuf.send.req_s = s; assert(size < 1600); memmove(&nsipcbuf.send.req_buf, buf, size); nsipcbuf.send.req_size = size; nsipcbuf.send.req_flags = flags; return nsipc(NSREQ_SEND); } int nsipc_socket(int domain, int type, int protocol) { nsipcbuf.socket.req_domain = domain; nsipcbuf.socket.req_type = type; nsipcbuf.socket.req_protocol = protocol; return nsipc(NSREQ_SOCKET); }