提交 7198b18c 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

Connect sys_{socket,bind,listen,accept} to lwIP

上级 3cf099da
struct file { struct file {
enum { FD_NONE, FD_PIPE, FD_INODE } type; enum { FD_NONE, FD_PIPE, FD_INODE, FD_SOCKET } type;
int ref; // reference count int ref; // reference count
char readable; char readable;
char writable; char writable;
int socket;
struct pipe *pipe; struct pipe *pipe;
struct inode *ip; struct inode *ip;
u32 off; u32 off;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "lwip/ip.h" #include "lwip/ip.h"
#include "lwip/netif.h" #include "lwip/netif.h"
#include "lwip/dhcp.h" #include "lwip/dhcp.h"
#include "lwip/sockets.h"
#include "netif/etharp.h" #include "netif/etharp.h"
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
...@@ -14,6 +15,8 @@ ...@@ -14,6 +15,8 @@
#include "kernel.h" #include "kernel.h"
#include "queue.h" #include "queue.h"
#include "proc.h" #include "proc.h"
#include "fs.h"
#include "file.h"
void void
netfree(void *va) netfree(void *va)
...@@ -199,27 +202,63 @@ initnet(void) ...@@ -199,27 +202,63 @@ initnet(void)
} }
long long
sys_socket(int domain, int type, int protocol) netsocket(int domain, int type, int protocol)
{ {
return -1; return lwip_socket(domain, type, protocol);
} }
long long
sys_bind(int sock, void *xaddr, int xaddrlen) netbind(int sock, void *xaddr, int xaddrlen)
{ {
return -1; void *addr;
long r;
addr = kmalloc(xaddrlen);
if (addr == NULL)
return -1;
if (umemcpy(addr, xaddr, xaddrlen))
return -1;
r = lwip_bind(sock, addr, xaddrlen);
kmfree(addr);
return r;
} }
long long
sys_listen(int sock, int backlog) netlisten(int sock, int backlog)
{ {
return -1; return lwip_listen(sock, backlog);
} }
long long
sys_accept(int sock, void *xaddr, void *xaddrlen) netaccept(int sock, void *xaddr, void *xaddrlen)
{ {
return -1; socklen_t *lenptr = xaddrlen;
socklen_t len;
void *addr;
int ss;
if (umemcpy(&len, lenptr, sizeof(*lenptr)))
return -1;
addr = kmalloc(len);
if (addr == NULL)
return -1;
ss = lwip_accept(sock, addr, &len);
if (ss < 0) {
kmfree(addr);
return ss;
}
if (kmemcpy(xaddrlen, &len, sizeof(len)) || kmemcpy(xaddr, addr, len)) {
lwip_close(ss);
kmfree(addr);
return -1;
}
return ss;
} }
#else #else
...@@ -236,25 +275,25 @@ netrx(void *va, u16 len) ...@@ -236,25 +275,25 @@ netrx(void *va, u16 len)
} }
long long
sys_socket(int domain, int type, int protocol) netsocket(int domain, int type, int protocol)
{ {
return -1; return -1;
} }
long long
sys_bind(int sock, void *xaddr, int xaddrlen) netbind(int sock, void *xaddr, int xaddrlen)
{ {
return -1; return -1;
} }
long long
sys_listen(int sock, int backlog) netlisten(int sock, int backlog)
{ {
return -1; return -1;
} }
long long
sys_accept(int sock, void *xaddr, void *xaddrlen) netaccept(int sock, void *xaddr, void *xaddrlen)
{ {
return -1; return -1;
} }
......
...@@ -416,3 +416,119 @@ sys_pipe(void) ...@@ -416,3 +416,119 @@ sys_pipe(void)
fd[1] = fd1; fd[1] = fd1;
return 0; return 0;
} }
static void
freesocket(int fd)
{
fileclose(myproc()->ofile[fd]);
myproc()->ofile[fd] = 0;
}
static int
getsocket(int fd, struct file **ret)
{
struct file *f;
if (fd < 0 || fd >= NOFILE || (f=myproc()->ofile[fd]) == 0)
return -1;
if (f->type != FD_SOCKET)
return -1;
*ret = f;
return 0;
}
static int
allocsocket(struct file **rf, int *rfd)
{
struct file *f;
int fd;
f = filealloc();
if (f == NULL)
return -1;
fd = fdalloc(f);
if (fd < 0) {
fileclose(f);
return fd;
}
f->type = FD_SOCKET;
f->off = 0;
f->readable = 1;
f->writable = 1;
*rf = f;
*rfd = fd;
return 0;
}
long
sys_socket(int domain, int type, int protocol)
{
extern long netsocket(int domain, int type, int protocol);
struct file *f;
int fd;
int s;
if (allocsocket(&f, &fd))
return -1;
s = netsocket(domain, type, protocol);
if (s < 0) {
myproc()->ofile[fd] = 0;
fileclose(f);
return s;
}
f->socket = s;
return fd;
}
long
sys_bind(int xsock, void *xaddr, int xaddrlen)
{
extern long netbind(int, void*, int);
struct file *f;
if (getsocket(xsock, &f))
return -1;
return netbind(f->socket, xaddr, xaddrlen);
}
long
sys_listen(int xsock, int backlog)
{
extern long netlisten(int, int);
struct file *f;
if (getsocket(xsock, &f))
return -1;
return netlisten(f->socket, backlog);
}
long
sys_accept(int xsock, void *xaddr, void *xaddrlen)
{
extern long netaccept(int, void*, void*);
struct file *f, *cf;
int cfd;
int ss;
if (getsocket(xsock, &f))
return -1;
if (allocsocket(&cf, &cfd))
return -1;
ss = netaccept(f->socket, xaddr, xaddrlen);
if (ss < 0) {
freesocket(cfd);
return ss;
}
cf->socket = ss;
return cfd;
}
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论