* same with xv6
[mascara-docs.git] / i386 / MIT / course / src / src.lab / lib / nsipc.c
blob98c61ae99a3758e96b330a29bbb4ca53f0a34391
1 #include <inc/ns.h>
2 #include <inc/lib.h>
3 #include <lwip/sockets.h>
5 #define debug 0
7 // Virtual address at which to receive page mappings containing client requests.
8 #define REQVA 0x0ffff000
9 union Nsipc nsipcbuf __attribute__((aligned(PGSIZE)));
11 // Send an IP request to the network server, and wait for a reply.
12 // The request body should be in nsipcbuf, and parts of the response
13 // may be written back to nsipcbuf.
14 // type: request code, passed as the simple integer IPC value.
15 // Returns 0 if successful, < 0 on failure.
16 static int
17 nsipc(unsigned type)
19 static envid_t nsenv;
20 if (nsenv == 0)
21 nsenv = ipc_find_env(ENV_TYPE_NS);
23 static_assert(sizeof(nsipcbuf) == PGSIZE);
25 if (debug)
26 cprintf("[%08x] nsipc %d\n", thisenv->env_id, type);
28 ipc_send(nsenv, type, &nsipcbuf, PTE_P|PTE_W|PTE_U);
29 return ipc_recv(NULL, NULL, NULL);
32 int
33 nsipc_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
35 int r;
37 nsipcbuf.accept.req_s = s;
38 if ((r = nsipc(NSREQ_ACCEPT)) >= 0) {
39 struct Nsret_accept *ret = &nsipcbuf.acceptRet;
40 memmove(addr, &ret->ret_addr, ret->ret_addrlen);
41 *addrlen = ret->ret_addrlen;
43 return r;
46 int
47 nsipc_bind(int s, struct sockaddr *name, socklen_t namelen)
49 nsipcbuf.bind.req_s = s;
50 memmove(&nsipcbuf.bind.req_name, name, namelen);
51 nsipcbuf.bind.req_namelen = namelen;
52 return nsipc(NSREQ_BIND);
55 int
56 nsipc_shutdown(int s, int how)
58 nsipcbuf.shutdown.req_s = s;
59 nsipcbuf.shutdown.req_how = how;
60 return nsipc(NSREQ_SHUTDOWN);
63 int
64 nsipc_close(int s)
66 nsipcbuf.close.req_s = s;
67 return nsipc(NSREQ_CLOSE);
70 int
71 nsipc_connect(int s, const struct sockaddr *name, socklen_t namelen)
73 nsipcbuf.connect.req_s = s;
74 memmove(&nsipcbuf.connect.req_name, name, namelen);
75 nsipcbuf.connect.req_namelen = namelen;
76 return nsipc(NSREQ_CONNECT);
79 int
80 nsipc_listen(int s, int backlog)
82 nsipcbuf.listen.req_s = s;
83 nsipcbuf.listen.req_backlog = backlog;
84 return nsipc(NSREQ_LISTEN);
87 int
88 nsipc_recv(int s, void *mem, int len, unsigned int flags)
90 int r;
92 nsipcbuf.recv.req_s = s;
93 nsipcbuf.recv.req_len = len;
94 nsipcbuf.recv.req_flags = flags;
96 if ((r = nsipc(NSREQ_RECV)) >= 0) {
97 assert(r < 1600 && r <= len);
98 memmove(mem, nsipcbuf.recvRet.ret_buf, r);
101 return r;
105 nsipc_send(int s, const void *buf, int size, unsigned int flags)
107 nsipcbuf.send.req_s = s;
108 assert(size < 1600);
109 memmove(&nsipcbuf.send.req_buf, buf, size);
110 nsipcbuf.send.req_size = size;
111 nsipcbuf.send.req_flags = flags;
112 return nsipc(NSREQ_SEND);
116 nsipc_socket(int domain, int type, int protocol)
118 nsipcbuf.socket.req_domain = domain;
119 nsipcbuf.socket.req_type = type;
120 nsipcbuf.socket.req_protocol = protocol;
121 return nsipc(NSREQ_SOCKET);