From: David van Moolenbroek Date: Mon, 13 Feb 2017 22:52:16 +0000 (+0000) Subject: Retire lwip: the previous lwIP-based TCP/IP service X-Git-Url: http://zhaoyanbai.com/repos/Bv9ARM.ch04.html?a=commitdiff_plain;h=refs%2Fchanges%2F32%2F3432%2F1;p=minix.git Retire lwip: the previous lwIP-based TCP/IP service Change-Id: Id9bbf96344a6e9d796f6773547588a981e70bf0f --- diff --git a/distrib/sets/lists/minix-base/mi b/distrib/sets/lists/minix-base/mi index 38a9ad7cf..c87e3eb62 100644 --- a/distrib/sets/lists/minix-base/mi +++ b/distrib/sets/lists/minix-base/mi @@ -177,7 +177,7 @@ ./etc/system.conf.d/hello minix-base ./etc/system.conf.d/inet minix-base ./etc/system.conf.d/ipc minix-base -./etc/system.conf.d/lwip minix-base +./etc/system.conf.d/lwip minix-base obsolete ./etc/system.conf.d/random minix-base ./etc/system.conf.d/uds minix-base ./etc/system.conf.d/usb_hub minix-base @@ -237,7 +237,7 @@ ./service/is minix-base ./service/isofs minix-base ./service/log minix-base -./service/lwip minix-base +./service/lwip minix-base obsolete ./service/memory minix-base ./service/mfs minix-base ./service/mib minix-base diff --git a/distrib/sets/lists/minix-comp/mi b/distrib/sets/lists/minix-comp/mi index f17be8a51..3c37fce67 100644 --- a/distrib/sets/lists/minix-comp/mi +++ b/distrib/sets/lists/minix-comp/mi @@ -1221,7 +1221,7 @@ ./usr/include/minix/mmio.h minix-comp ./usr/include/minix/mthread.h minix-comp ./usr/include/minix/netdriver.h minix-comp -./usr/include/minix/netsock.h minix-comp +./usr/include/minix/netsock.h minix-comp obsolete ./usr/include/minix/optset.h minix-comp ./usr/include/minix/padconf.h minix-comp ./usr/include/minix/param.h minix-comp @@ -1922,7 +1922,7 @@ ./usr/lib/bc/libnetdriver.a minix-comp bitcode ./usr/lib/bc/libnetpgp.a minix-comp bitcode ./usr/lib/bc/libnetpgpverify.a minix-comp bitcode -./usr/lib/bc/libnetsock.a minix-comp bitcode +./usr/lib/bc/libnetsock.a minix-comp bitcode,obsolete ./usr/lib/bc/libopcodes.a minix-comp bitcode,binutils ./usr/lib/bc/libpci.a minix-comp bitcode ./usr/lib/bc/libprop.a minix-comp bitcode @@ -2077,8 +2077,8 @@ ./usr/lib/libmthread_pic.a minix-comp ./usr/lib/libnetdriver.a minix-comp ./usr/lib/libnetdriver_pic.a minix-comp -./usr/lib/libnetsock.a minix-comp -./usr/lib/libnetsock_pic.a minix-comp +./usr/lib/libnetsock.a minix-comp obsolete +./usr/lib/libnetsock_pic.a minix-comp obsolete ./usr/lib/libobjc.a minix-comp gcc=45 ./usr/lib/libobjc_pic.a minix-comp gcc=45 ./usr/lib/libpci.a minix-comp diff --git a/distrib/sets/lists/minix-debug/mi b/distrib/sets/lists/minix-debug/mi index 9727f6cf0..88f9dbd36 100644 --- a/distrib/sets/lists/minix-debug/mi +++ b/distrib/sets/lists/minix-debug/mi @@ -88,7 +88,7 @@ ./usr/lib/libnetdriver_g.a minix-debug debuglib ./usr/lib/libnetpgp_g.a minix-debug debuglib ./usr/lib/libnetpgpverify_g.a minix-debug debuglib -./usr/lib/libnetsock_g.a minix-debug debuglib +./usr/lib/libnetsock_g.a minix-debug debuglib,obsolete ./usr/lib/libobjc_g.a minix-debug gcc=5,debuglib ./usr/lib/libopcodes_g.a minix-debug debuglib ./usr/lib/libpci_g.a minix-debug debuglib @@ -186,7 +186,7 @@ ./usr/libdata/debug/service/is.debug minix-debug debug ./usr/libdata/debug/service/isofs.debug minix-debug debug ./usr/libdata/debug/service/log.debug minix-debug debug -./usr/libdata/debug/service/lwip.debug minix-debug debug +./usr/libdata/debug/service/lwip.debug minix-debug debug,obsolete ./usr/libdata/debug/service/memory.debug minix-debug debug ./usr/libdata/debug/service/mfs.debug minix-debug debug ./usr/libdata/debug/service/mib.debug minix-debug debug diff --git a/etc/rs.inet b/etc/rs.inet index 128301fe4..7cadab4f2 100755 --- a/etc/rs.inet +++ b/etc/rs.inet @@ -1,6 +1,6 @@ #!/bin/sh -# Recovery script for INET/lwip. It restarts daemons dependent on it in order +# Recovery script for INET. It restarts daemons dependent on it in order # to recover TCP state. kill_by_name() @@ -64,14 +64,8 @@ kill_by_name syslogd # Wait a moment to let daemons clean themselves up sleep 3 -if [ X`/bin/sysenv lwip` = Xyes ] -then - minix-service up /service/lwip -script /etc/rs.inet -dev /dev/ip -restarts $restarts - dhcpd --lwip & -else - minix-service up /service/inet -script /etc/rs.inet -dev /dev/ip -restarts $restarts - daemonize dhcpd -fi +minix-service up /service/inet -script /etc/rs.inet -dev /dev/ip -restarts $restarts +daemonize dhcpd daemonize nonamed -L daemonize syslogd diff --git a/etc/usr/rc b/etc/usr/rc index 1d5bb3e84..529baa396 100644 --- a/etc/usr/rc +++ b/etc/usr/rc @@ -191,12 +191,8 @@ start) arg="-args \"instance=$instance$arg\"" eval up $driver -label $label $arg -period 5HZ done - if [ X`/bin/sysenv lwip` = Xyes ] - then - up lwip -script /etc/rs.inet -dev /dev/ip - else - up inet -script /etc/rs.inet -dev /dev/ip - fi + + up inet -script /etc/rs.inet -dev /dev/ip # pty needs to know the "tty" group ID up pty -dev /dev/ptmx -args "gid=`stat -f '%g' /dev/ptmx`" @@ -371,13 +367,7 @@ start) if grep -s 'psip0.*default' /etc/inet.conf >/dev/null then ifconfig -h 10.0.0.1 else - if [ X`/bin/sysenv lwip` = Xyes ] - then - dhcpd --lwip & - echo -n " dhcpd" - else - daemonize dhcpd - fi + daemonize dhcpd fi daemonize nonamed -L if [ -f "$DAEMONS" ] diff --git a/lib/Makefile b/lib/Makefile index 434b969b6..3d30851d5 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -32,6 +32,7 @@ SUBDIR+= ../minix/lib/libasyn \ ../minix/lib/libexec \ ../minix/lib/libfsdriver \ ../minix/lib/libinputdriver \ + ../minix/lib/liblwip \ ../minix/lib/libminc \ ../minix/lib/libminixfs \ ../minix/lib/libnetdriver \ @@ -46,11 +47,6 @@ SUBDIR+= ../minix/lib/libasyn \ SUBDIR+= ../minix/lib/libgcc_s_empty .endif -.if (${MKLWIP} == "yes") -SUBDIR+= ../minix/lib/liblwip \ - ../minix/lib/libnetsock -.endif - .if (${MACHINE_ARCH} == "i386") SUBDIR+= ../minix/lib/libacpi \ ../minix/lib/libhgfs \ diff --git a/minix/include/minix/Makefile b/minix/include/minix/Makefile index f3edeb197..07e00bd18 100644 --- a/minix/include/minix/Makefile +++ b/minix/include/minix/Makefile @@ -22,7 +22,7 @@ INCS+= acpi.h audio_fw.h bitmap.h \ syslib.h sysutil.h timers.h type.h \ u64.h usb.h usb_ch9.h vbox.h \ vboxfs.h vboxif.h vboxtype.h vm.h \ - vfsif.h vtreefs.h libminixfs.h netsock.h \ + vfsif.h vtreefs.h libminixfs.h \ virtio.h .include diff --git a/minix/include/minix/netsock.h b/minix/include/minix/netsock.h deleted file mode 100644 index 63ad4c532..000000000 --- a/minix/include/minix/netsock.h +++ /dev/null @@ -1,160 +0,0 @@ -#ifndef __NET_SERVER_SOCKET_H__ -#define __NET_SERVER_SOCKET_H__ - -#include - -#include -#include -#include - -/* - * User can set this variable to make the debugging output differ between - * various users, e.g. "TCP" or "UDP" - */ -extern char * netsock_user_name; - -#define SOCK_TYPE_IP 0 -#define SOCK_TYPE_TCP 1 -#define SOCK_TYPE_UDP 2 -#define SOCK_TYPES 3 - -struct socket; -struct sock_req; - -typedef int (* sock_op_opcl_t)(struct socket *); -typedef int (* sock_op_io_t)(struct socket *, struct sock_req *, int blk); -typedef int (* sock_op_select_t)(struct socket *, unsigned int); -typedef int (* sock_op_select_reply_t)(struct socket *); - -struct sock_ops { - sock_op_opcl_t open; - sock_op_opcl_t close; - sock_op_io_t read; - sock_op_io_t write; - sock_op_io_t ioctl; - sock_op_select_t select; - sock_op_select_reply_t select_reply; -}; - -struct recv_q { - struct recv_q * next; - void * data; -}; - -#define SOCK_FLG_OP_PENDING 0x1 -#define SOCK_FLG_OP_IOCTL 0x10 -#define SOCK_FLG_OP_LISTENING 0x100 /* tcp socket is in a listening mode */ -#define SOCK_FLG_OP_CONNECTING 0x200 /* set when waiting for a connect */ -#define SOCK_FLG_OP_READING 0x400 /* reading operation in progress */ -#define SOCK_FLG_OP_WRITING 0x800 /* writing operation in progress */ -#define SOCK_FLG_CLOSED 0x1000 /* tcp socket has been closed do not - expect any more data */ -/* select() flags - they say what action do we monitor */ -#define SOCK_FLG_SEL_WRITE 0x100000 -#define SOCK_FLG_SEL_READ 0x200000 -#define SOCK_FLG_SEL_ERROR 0x400000 - -#define sock_select_set(sock) ((sock)->flags & (SOCK_FLG_SEL_WRITE | \ - SOCK_FLG_SEL_READ | SOCK_FLG_SEL_ERROR)) -#define sock_select_read_set(sock) ((sock)->flags & SOCK_FLG_SEL_READ) -#define sock_select_write_set(sock) ((sock)->flags & SOCK_FLG_SEL_WRITE) -#define sock_select_rw_set(sock) ((sock)->flags & (SOCK_FLG_SEL_READ | \ - SOCK_FLG_SEL_WRITE)) -#define sock_select_error_set(sock) ((sock)->flags & SOCK_FLG_SEL_ERROR) -#define sock_clear_select(sock) do { \ - (sock)->flags &= ~(SOCK_FLG_SEL_READ | SOCK_FLG_SEL_WRITE | \ - SOCK_FLG_SEL_ERROR); \ -} while (0) - -struct sock_req { - enum { - SOCK_REQ_READ, - SOCK_REQ_WRITE, - SOCK_REQ_IOCTL - } type; - devminor_t minor; - endpoint_t endpt; - cp_grant_id_t grant; - union { - size_t size; /* for SOCK_REQ_READ, SOCK_REQ_WRITE */ - unsigned long req; /* for SOCK_REQ_IOCTL */ - }; - int flags; - cdev_id_t id; -}; - -struct socket { - int type; - u32_t flags; - unsigned long usr_flags; - void * pcb; - struct sock_ops * ops; - void * buf; - size_t buf_size; - struct sock_req req; - void * shm; - size_t shm_size; - endpoint_t select_ep; - struct recv_q * recv_head; - struct recv_q * recv_tail; - unsigned recv_data_size; /* sum of data enqueued */ - void * data; -}; - -/* - * Each component needs to provide a method how to initially open a socket. - * The rest is handled byt the socket library. - */ -int socket_open(devminor_t minor); - -#define get_sock_num(x) ((long int) ((x) - socket_array)) -#define is_valid_sock_num(x) (x < MAX_SOCKETS) -#define get_sock(x) &socket_array[x] - -#define MAX_SOCKETS 255 /* FIXME as log as the sockets are identified by the - minor device number 255 is ok */ -#define MAX_DEVS 5 -#define RESERVED (SOCK_TYPES + MAX_DEVS) /* rounded to 8 */ - -extern struct socket socket_array[MAX_SOCKETS]; - -void socket_request(message * m, int ipc_status); -void mq_process(void); - -struct socket * get_unused_sock(void); -struct socket * get_nic_sock(unsigned dev); - -void send_req_reply(struct sock_req * req, int status); - -typedef void (* recv_data_free_fn)(void *); - -int sock_enqueue_data(struct socket * sock, void * data, unsigned size); -void * sock_dequeue_data(struct socket * sock); -void sock_dequeue_data_all(struct socket * sock, - recv_data_free_fn data_free); - -void sock_select_notify(struct socket * sock); - -static inline void * debug_malloc(size_t s) -{ - void * ret; - - ret = malloc(s); - // printf("allocated %p size %d\n", ret, s); - return ret; -} - -#define debug_free(x) do { \ - if (0) \ - printf("free called from %s:%d %s freeing %p\n", __FILE__, \ - __LINE__, __func__, (x)); \ - free(x); \ -} while(0) - -int generic_op_select(struct socket * sock, unsigned int sel); -int generic_op_select_reply(struct socket * sock); - -/* a function thr user has to provide to reply to the posix server */ -void posix_reply(endpoint_t ep, message * m); - -#endif /* __NET_SERVER_SOCKET_H__ */ diff --git a/minix/lib/Makefile b/minix/lib/Makefile index d120a8172..3169f8712 100644 --- a/minix/lib/Makefile +++ b/minix/lib/Makefile @@ -14,6 +14,7 @@ SUBDIR+= libdevman SUBDIR+= libexec SUBDIR+= libfsdriver SUBDIR+= libinputdriver +SUBDIR+= liblwip SUBDIR+= libminc SUBDIR+= libminixfs SUBDIR+= libnetdriver @@ -28,11 +29,6 @@ SUBDIR+= libvtreefs SUBDIR+= libgcc_s_empty .endif -.if (${MKLWIP} == "yes") -SUBDIR+= liblwip -SUBDIR+= libnetsock -.endif - .if (${MACHINE_ARCH} == "i386") SUBDIR+= libacpi SUBDIR+= libhgfs diff --git a/minix/lib/libchardriver/chardriver.c b/minix/lib/libchardriver/chardriver.c index 12b95f391..0f47dbff2 100644 --- a/minix/lib/libchardriver/chardriver.c +++ b/minix/lib/libchardriver/chardriver.c @@ -208,7 +208,7 @@ static void chardriver_reply(message *mess, int ipc_status, int r) /* FIXME: we should be able to check FLAGS against * CDEV_NONBLOCK here, but in practice, several drivers do not * send a reply through this path (eg TTY) or simply do not - * implement nonblocking calls properly (eg audio, LWIP). + * implement nonblocking calls properly (eg audio). */ #if 0 if (mess->m_vfs_lchardriver_readwrite.flags & CDEV_NONBLOCK) diff --git a/minix/lib/libnetsock/Makefile b/minix/lib/libnetsock/Makefile deleted file mode 100644 index 5fd2efc05..000000000 --- a/minix/lib/libnetsock/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -CPPFLAGS+= -D_MINIX_SYSTEM - -LIB = netsock - -CPPFLAGS += -I${.CURDIR}/include/ -D_SYSTEM -CPPFLAGS+= -I${.CURDIR}/../../lib/liblwip/include -I${.CURDIR}/../../lib/liblwip/include/ipv4 -I${.CURDIR}/../../lib/liblwip/include/ipv6 -CFLAGS += -Wall -Wextra -std=c99 - -SRCS += socket.c - -.include diff --git a/minix/lib/libnetsock/socket.c b/minix/lib/libnetsock/socket.c deleted file mode 100644 index 2207fdd54..000000000 --- a/minix/lib/libnetsock/socket.c +++ /dev/null @@ -1,560 +0,0 @@ -/* - * This file implements handling of socket-related requests from VFS - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include - -char * netsock_user_name = NULL; -#define NETSOCK_USER_NAME (netsock_user_name ? netsock_user_name : "NETSOCK") - -#define debug_print(str, ...) printf("%s : %s:%d : " str "\n", \ - NETSOCK_USER_NAME, __func__, __LINE__, ##__VA_ARGS__) - -#if 0 -#define debug_sock_print(...) debug_print(__VA_ARGS__) -#else -#define debug_sock_print(...) -#endif - -#if 0 -#define debug_sock_select_print(...) debug_print(__VA_ARGS__) -#else -#define debug_sock_select_print(...) debug_sock_print(__VA_ARGS__) -#endif - -#define netsock_panic(str, ...) panic("%s : " str, NETSOCK_USER_NAME, \ - ##__VA_ARGS__) -#define netsock_error(str, ...) printf("%s : " str, NETSOCK_USER_NAME, \ - ##__VA_ARGS__) - - -struct socket socket_array[MAX_SOCKETS]; - -static int netsock_open(devminor_t minor, int access, endpoint_t user_endpt); -static int netsock_close(devminor_t minor); -static ssize_t netsock_read(devminor_t minor, u64_t position, endpoint_t endpt, - cp_grant_id_t grant, size_t size, int flags, cdev_id_t id); -static ssize_t netsock_write(devminor_t minor, u64_t position, - endpoint_t endpt, cp_grant_id_t grant, size_t size, int flags, - cdev_id_t id); -static int netsock_ioctl(devminor_t minor, unsigned long request, - endpoint_t endpt, cp_grant_id_t grant, int flags, - endpoint_t user_endpt, cdev_id_t id); -static int netsock_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id); -static int netsock_select(devminor_t minor, unsigned int ops, - endpoint_t endpt); - -static struct chardriver netsock_tab = { - .cdr_open = netsock_open, - .cdr_close = netsock_close, - .cdr_read = netsock_read, - .cdr_write = netsock_write, - .cdr_ioctl = netsock_ioctl, - .cdr_cancel = netsock_cancel, - .cdr_select = netsock_select -}; - -#define recv_q_alloc() debug_malloc(sizeof(struct recv_q)) -#define recv_q_free debug_free - -struct mq { - struct sock_req req; - struct mq * prev; - struct mq * next; -}; - -#define mq_alloc() debug_malloc(sizeof(struct mq)) -#define mq_free debug_free - -static struct mq * mq_head, *mq_tail; - -static int mq_enqueue(struct sock_req * req) -{ - struct mq * mq; - - debug_sock_print("sock %d op %d", req->minor, req->type); - mq = mq_alloc(); - - if (mq == NULL) - return -1; - - mq->next = NULL; - mq->req = *req; - - if (mq_head) { - mq->prev = mq_tail; - mq_tail->next = mq; - mq_tail = mq; - } - else { - mq->prev = NULL; - mq_head = mq_tail = mq; - } - - return 0; -} - -__unused static struct mq * mq_dequeue_head(void) -{ - struct mq * ret; - - if (!mq_head) - return NULL; - - ret = mq_head; - - if (mq_head != mq_tail) { - mq_head = mq_head->next; - mq_head->prev = NULL; - } else - mq_head = mq_tail = NULL; - - debug_sock_print("socket %d\n", ret->req.minor); - - return ret; -} - -static void mq_dequeue(struct mq * mq) -{ - if (mq_head == mq_tail) - mq_head = mq_tail = NULL; - else { - if (mq->prev == NULL) { - mq_head = mq->next; - mq_head->prev = NULL; - } else - mq->prev->next = mq->next; - if (mq->next == NULL) { - mq_tail = mq->prev; - mq_tail->next = NULL; - } else - mq->next->prev = mq->prev; - } -} - -static int mq_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id) -{ - struct mq * mq; - - for (mq = mq_tail; mq; mq = mq->prev) { - if (minor == mq->req.minor && endpt == mq->req.endpt && - id == mq->req.id) { - debug_sock_print("socket %d\n", minor); - break; - } - } - - if (mq) { - mq_dequeue(mq); - mq_free(mq); - } - - /* FIXME: shouldn't this return (!!mq) ? */ - return 1; -} - -int sock_enqueue_data(struct socket * sock, void * data, unsigned size) -{ - struct recv_q * r; - - if (!(r = recv_q_alloc())) - return ENOMEM; - - r->data = data; - r->next = NULL; - - if (sock->recv_head) { - sock->recv_tail->next = r; - sock->recv_tail = r; - } else { - sock->recv_head = sock->recv_tail = r; - } - - assert(size > 0); - sock->recv_data_size += size; - - return OK; -} - -void * sock_dequeue_data(struct socket * sock) -{ - void * data; - struct recv_q * r; - - if ((r = sock->recv_head)) { - data = r->data; - if (!(sock->recv_head = r->next)) - sock->recv_tail = NULL; - recv_q_free(r); - - return data; - } - - return NULL; -} - -void sock_dequeue_data_all(struct socket * sock, - recv_data_free_fn data_free) -{ - void * data; - - while ((data = sock_dequeue_data(sock))) - data_free(data); - sock->recv_data_size = 0; -} - -void send_req_reply(struct sock_req * req, int status) -{ - if (status == EDONTREPLY) - return; - - chardriver_reply_task(req->endpt, req->id, status); -} - -void sock_select_notify(struct socket * sock) -{ - unsigned int ops; - - debug_sock_select_print("socket num %ld", get_sock_num(sock)); - assert(sock->select_ep != NONE); - - ops = sock->ops->select_reply(sock); - if (ops == 0) { - debug_sock_select_print("called from %p sflags 0x%x TXsz %d RXsz %d\n", - __builtin_return_address(0), sock->flags, - sock->buf_size, sock->recv_data_size); - return; - } - - chardriver_reply_select(sock->select_ep, get_sock_num(sock), ops); - - sock_clear_select(sock); - sock->select_ep = NONE; -} - -struct socket * get_unused_sock(void) -{ - int i; - - for (i = SOCK_TYPES + MAX_DEVS; i < MAX_SOCKETS; i++) { - if (socket_array[i].ops == NULL) { - /* clear it all */ - memset(&socket_array[i], 0, sizeof(struct socket)); - return &socket_array[i]; - } - } - - return NULL; -} - -static int socket_request_socket(struct socket * sock, struct sock_req * req) -{ - int r, blocking = (req->flags & CDEV_NONBLOCK) ? 0 : 1; - - switch (req->type) { - case SOCK_REQ_READ: - if (sock->ops && sock->ops->read) - r = sock->ops->read(sock, req, blocking); - else - r = EINVAL; - break; - case SOCK_REQ_WRITE: - if (sock->ops && sock->ops->write) - r = sock->ops->write(sock, req, blocking); - else - r = EINVAL; - break; - case SOCK_REQ_IOCTL: - if (sock->ops && sock->ops->ioctl) - r = sock->ops->ioctl(sock, req, blocking); - else - r = EINVAL; - break; - default: - netsock_panic("cannot happen!"); - } - - return r; -} - -static int netsock_open(devminor_t minor, int UNUSED(access), - endpoint_t UNUSED(user_endpt)) -{ - int r; - - if ((r = socket_open(minor)) < 0) - return r; - - return CDEV_CLONED | r; -} - -static int netsock_close(devminor_t minor) -{ - struct socket *sock; - - if (!(sock = get_sock(minor))) - return EINVAL; - - if (sock->ops && sock->ops->close) { - sock->flags &= ~SOCK_FLG_OP_PENDING; - - return sock->ops->close(sock); - } else - return EINVAL; -} - -static int netsock_request(struct socket *sock, struct sock_req *req) -{ - const char *o __unused; - - /* - * If an operation is pending (blocking operation) or writing is - * still going on and we're reading, suspend the new operation - */ - if ((sock->flags & SOCK_FLG_OP_PENDING) || - (req->type == SOCK_REQ_READ && - sock->flags & SOCK_FLG_OP_WRITING)) { - if (sock->flags & SOCK_FLG_OP_READING) - o = "READ"; - else if (sock->flags & SOCK_FLG_OP_WRITING) - o = "WRITE"; - else - o = "non R/W op"; - debug_sock_print("socket %ld is busy by %s flgs 0x%x\n", - get_sock_num(sock), o, sock->flags); - - if (mq_enqueue(req) != 0) { - debug_sock_print("Enqueuing suspended call failed"); - return ENOMEM; - } - - return EDONTREPLY; - } - - return socket_request_socket(sock, req); -} - -static ssize_t netsock_read(devminor_t minor, u64_t UNUSED(position), - endpoint_t endpt, cp_grant_id_t grant, size_t size, int flags, - cdev_id_t id) -{ - struct socket *sock; - struct sock_req req; - - if (!(sock = get_sock(minor))) - return EINVAL; - - /* Build a request record for this request. */ - req.type = SOCK_REQ_READ; - req.minor = minor; - req.endpt = endpt; - req.grant = grant; - req.size = size; - req.flags = flags; - req.id = id; - - /* Process the request. */ - return netsock_request(sock, &req); -} - -static ssize_t netsock_write(devminor_t minor, u64_t UNUSED(position), - endpoint_t endpt, cp_grant_id_t grant, size_t size, int flags, - cdev_id_t id) -{ - struct socket *sock; - struct sock_req req; - - if (!(sock = get_sock(minor))) - return EINVAL; - - /* Build a request record for this request. */ - req.type = SOCK_REQ_WRITE; - req.minor = minor; - req.endpt = endpt; - req.grant = grant; - req.size = size; - req.flags = flags; - req.id = id; - - /* Process the request. */ - return netsock_request(sock, &req); -} - -static int netsock_ioctl(devminor_t minor, unsigned long request, - endpoint_t endpt, cp_grant_id_t grant, int flags, - endpoint_t UNUSED(user_endpt), cdev_id_t id) -{ - struct socket *sock; - struct sock_req req; - - if (!(sock = get_sock(minor))) - return EINVAL; - - /* Build a request record for this request. */ - req.type = SOCK_REQ_IOCTL; - req.minor = minor; - req.req = request; - req.endpt = endpt; - req.grant = grant; - req.flags = flags; - req.id = id; - - /* Process the request. */ - return netsock_request(sock, &req); -} - -static int netsock_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id) -{ - struct socket *sock; - - if (!(sock = get_sock(minor))) - return EDONTREPLY; - - debug_sock_print("socket num %ld", get_sock_num(sock)); - - /* Cancel the last operation in the queue */ - if (mq_cancel(minor, endpt, id)) - return EINTR; - - /* Cancel any ongoing blocked read */ - if ((sock->flags & SOCK_FLG_OP_PENDING) && - (sock->flags & SOCK_FLG_OP_READING) && - endpt == sock->req.endpt && id == sock->req.id) { - sock->flags &= ~SOCK_FLG_OP_PENDING; - return EINTR; - } - - /* The request may not be found. This is OK. Do not reply. */ - return EDONTREPLY; -} - -static int netsock_select(devminor_t minor, unsigned int ops, endpoint_t endpt) -{ - struct socket *sock; - int r; - - /* - * Select is always executed immediately and is never suspended. - * Although, it sets actions which must be monitored - */ - if (!(sock = get_sock(minor))) - return EBADF; - - assert(sock->select_ep == NONE || sock->select_ep == endpt); - - if (sock->ops && sock->ops->select) { - sock->select_ep = endpt; - r = sock->ops->select(sock, ops); - if (!sock_select_set(sock)) - sock->select_ep = NONE; - } else - r = EINVAL; - - return r; -} - -void socket_request(message * m, int ipc_status) -{ - debug_sock_print("request %d", m->m_type); - - /* Let the chardriver library decode the request for us. */ - chardriver_process(&netsock_tab, m, ipc_status); -} - -void mq_process(void) -{ - struct mq * mq; - struct socket * sock; - int r; - - mq = mq_head; - - while(mq) { - struct mq * next = mq->next; - - sock = get_sock(mq->req.minor); - if (!(sock->flags & SOCK_FLG_OP_PENDING) && - !(mq->req.type == SOCK_REQ_READ && - sock->flags & SOCK_FLG_OP_WRITING)) { - debug_sock_print("resuming op on sock %ld\n", - get_sock_num(sock)); - sock->req = mq->req; - r = socket_request_socket(sock, &sock->req); - send_req_reply(&sock->req, r); - mq_dequeue(mq); - mq_free(mq); - return; - } - - mq = next; - } -} - -int generic_op_select(struct socket * sock, unsigned int sel) -{ - int retsel = 0; - - debug_sock_print("socket num %ld 0x%x", get_sock_num(sock), sel); - - /* in this case any operation would block, no error */ - if (sock->flags & SOCK_FLG_OP_PENDING) { - if (sel & CDEV_NOTIFY) { - if (sel & CDEV_OP_RD) - sock->flags |= SOCK_FLG_SEL_READ; - if (sel & CDEV_OP_WR) - sock->flags |= SOCK_FLG_SEL_WRITE; - /* FIXME we do not monitor error */ - } - return 0; - } - - if (sel & CDEV_OP_RD) { - if (sock->recv_head) - retsel |= CDEV_OP_RD; - else if (sel & CDEV_NOTIFY) - sock->flags |= SOCK_FLG_SEL_READ; - } - /* FIXME generic packet socket never blocks on write */ - if (sel & CDEV_OP_WR) - retsel |= CDEV_OP_WR; - /* FIXME CDEV_OP_ERR is ignored, we do not generate exceptions */ - - return retsel; -} - -int generic_op_select_reply(struct socket * sock) -{ - unsigned int sel = 0; - - assert(sock->select_ep != NONE); - debug_sock_print("socket num %ld", get_sock_num(sock)); - - /* unused for generic packet socket, see generic_op_select() */ - assert((sock->flags & (SOCK_FLG_SEL_WRITE | SOCK_FLG_SEL_ERROR)) == 0); - - if (sock->flags & SOCK_FLG_OP_PENDING) { - debug_sock_print("WARNING socket still blocking!"); - return 0; - } - - if (sock->flags & SOCK_FLG_SEL_READ && sock->recv_head) - sel |= CDEV_OP_RD; - - if (sel) - sock->flags &= ~(SOCK_FLG_SEL_WRITE | SOCK_FLG_SEL_READ | - SOCK_FLG_SEL_ERROR); - - return sel; -} diff --git a/minix/net/Makefile b/minix/net/Makefile index 223f74188..67fab21a8 100644 --- a/minix/net/Makefile +++ b/minix/net/Makefile @@ -2,11 +2,6 @@ .if ${MKIMAGEONLY} == "no" SUBDIR+= inet - -. if ${MKLWIP} == "yes" -SUBDIR+= lwip -. endif # ${MKLWIP} == "yes" - SUBDIR+= uds .endif # ${MKIMAGEONLY} == "no" diff --git a/minix/net/lwip/Makefile b/minix/net/lwip/Makefile deleted file mode 100644 index d82950a25..000000000 --- a/minix/net/lwip/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -# Makefile for lwip server. -.include - -PROG= lwip -SRCS= lwip.c \ - driver.c \ - udp.c \ - tcp.c \ - raw_ip.c \ - inet_config.c \ - eth.c \ - rtinfo.c - -FILES=${PROG}.conf -FILESNAME=${PROG} -FILESDIR= /etc/system.conf.d - -.PATH: ${.CURDIR}/generic - -DPADD+= ${LIBCHARDRIVER} ${LIBSYS} ${LIBTIMERS} ${LIBLWIP} ${LIBNETSOCK} -LDADD+= -lchardriver -lsys -ltimers -llwip -lnetsock - -WARNS?=2 - -CPPFLAGS+= -I${NETBSDSRCDIR}/minix/lib/liblwip/include -CPPFLAGS+= -I${NETBSDSRCDIR}/minix/lib/liblwip/include/ipv4 -CPPFLAGS+= -I${NETBSDSRCDIR}/minix/lib/liblwip/include/ipv6 -CPPFLAGS+= -D_SYSTEM=1 - -CFLAGS+= -std=c99 - -.include diff --git a/minix/net/lwip/driver.c b/minix/net/lwip/driver.c deleted file mode 100644 index 71a09b3e6..000000000 --- a/minix/net/lwip/driver.c +++ /dev/null @@ -1,816 +0,0 @@ -/* - * This file implements handling of meesagges send by drivers - */ - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "proto.h" -#include "driver.h" - -#if 0 -#define debug_drv_print(str, ...) printf("LWIP %s:%d : " str "\n", \ - __func__, __LINE__, ##__VA_ARGS__) -#else -#define debug_drv_print(...) debug_print(__VA_ARGS__) -#endif - -#define RAW_BUF_SIZE (32 << 10) - -static struct nic devices[MAX_DEVS]; - -static ip_addr_t ip_addr_none = { IPADDR_NONE }; - -void nic_assign_driver(const char * dev_type, - unsigned int dev_num, - const char * driver_name, - unsigned int instance, - int is_default) -{ - struct nic * nic; - - if (strcmp(dev_type, "eth") != 0) { - printf("LWIP : Cannot handle other than ethernet devices, " - "ignoring '%s%d'\n", dev_type, dev_num); - return; - } - - nic = &devices[dev_num]; - snprintf(nic->name, NIC_NAME_LEN, "%s%d", dev_type, dev_num); - nic->name[NIC_NAME_LEN - 1] = '\0'; - snprintf(nic->drv_name, DRV_NAME_LEN, "%s_%d", driver_name, instance); - nic->drv_name[DRV_NAME_LEN - 1] = '\0'; - nic->is_default = is_default; - nic->netif.name[0] = 'e'; - nic->netif.name[1] = 't'; - nic->netif.num = dev_num; - - debug_print("/dev/%s driven by %s default = %d", - nic->name, nic->drv_name, is_default); -} - -static struct nic * lookup_nic_by_drv_ep(endpoint_t ep) -{ - int i; - - for (i = 0; i < MAX_DEVS; i++) { - if (devices[i].drv_ep == ep) - return &devices[i]; - } - - return NULL; -} - -static struct nic * lookup_nic_by_drv_name(const char * name) -{ - int i; - - for (i = 0; i < MAX_DEVS; i++) { - if (strcmp(devices[i].drv_name, name) == 0) - return &devices[i]; - } - - return NULL; -} - -static struct nic * lookup_nic_default(void) -{ - int i; - - for (i = 0; i < MAX_DEVS; i++) { - if (devices[i].is_default) - return &devices[i]; - } - - return NULL; -} - -struct nic * nic_get(int i) -{ - - if (i < 0 || i >= MAX_DEVS || devices[i].drv_ep == NONE) - return NULL; - - return &devices[i]; -} - -void nic_init_all(void) -{ - int i; - unsigned int g; - - for (i = 0; i < MAX_DEVS; i++) { - devices[i].drv_ep = NONE; - devices[i].is_default = 0; - - if (cpf_getgrants(&devices[i].rx_iogrant, 1) != 1) - panic("Cannot initialize grants"); - if (cpf_getgrants(&devices[i].rx_iovec[0].iov_grant, 1) != 1) - panic("Cannot initialize grants"); - if (cpf_getgrants(&devices[i].tx_iogrant, 1) != 1) - panic("Cannot initialize grants"); - for (g = 0; g < TX_IOVEC_NUM; g++) { - cp_grant_id_t * gid = &devices[i].tx_iovec[g].iov_grant; - if (cpf_getgrants(gid, 1) != 1) - panic("Cannot initialize grants"); - } - devices[i].raw_socket = NULL; - } -} - -static void driver_setup_read(struct nic * nic) -{ - message m; - - debug_print("device /dev/%s", nic->name); - //assert(nic->rx_pbuf == NULL); - if (!(nic->rx_pbuf == NULL)) { - panic("device /dev/%s rx_pbuf %p", nic->name, nic->rx_pbuf); - } - - if (!(nic->rx_pbuf = pbuf_alloc(PBUF_RAW, ETH_MAX_PACK_SIZE + ETH_CRC_SIZE, PBUF_RAM))) - panic("Cannot allocate rx pbuf"); - - if (cpf_setgrant_direct(nic->rx_iovec[0].iov_grant, - nic->drv_ep, (vir_bytes) nic->rx_pbuf->payload, - nic->rx_pbuf->len, CPF_WRITE) != OK) - panic("Failed to set grant"); - nic->rx_iovec[0].iov_size = nic->rx_pbuf->len; - - m.m_type = DL_READV_S; - m.m_net_netdrv_dl_readv_s.count = 1; - m.m_net_netdrv_dl_readv_s.grant = nic->rx_iogrant; - - if (asynsend(nic->drv_ep, &m) != OK) - panic("asynsend to the driver failed!"); -} - -static void nic_up(struct nic * nic, message * m) -{ - memcpy(nic->netif.hwaddr, m->m_netdrv_net_dl_conf.hw_addr, - sizeof(nic->netif.hwaddr)); - - debug_print("device %s is up MAC : %02x:%02x:%02x:%02x:%02x:%02x", - nic->name, - nic->netif.hwaddr[0], - nic->netif.hwaddr[1], - nic->netif.hwaddr[2], - nic->netif.hwaddr[3], - nic->netif.hwaddr[4], - nic->netif.hwaddr[5]); - - driver_setup_read(nic); - - netif_set_link_up(&nic->netif); - netif_set_up(&nic->netif); -} - -int driver_tx(struct nic * nic) -{ - struct packet_q * pkt; - unsigned int len; - message m; - - int err; - - debug_print("device /dev/%s", nic->name); - assert(nic->tx_buffer); - - pkt = driver_tx_head(nic); - if (pkt == NULL) { - debug_print("no packets enqueued"); - return 0; - } - - assert(pkt->buf_len <= nic->max_pkt_sz); - - if ((len = pkt->buf_len) < nic->min_pkt_sz) - len = nic->min_pkt_sz; - err = cpf_setgrant_direct(nic->tx_iovec[0].iov_grant, - nic->drv_ep, (vir_bytes) pkt->buf, - len, CPF_READ); - debug_print("packet len %d", len); - if (err != OK) - panic("Failed to set grant"); - nic->tx_iovec[0].iov_size = len; - - if (cpf_setgrant_direct(nic->tx_iogrant, nic->drv_ep, - (vir_bytes) &nic->tx_iovec, - sizeof(iovec_s_t), CPF_READ) != OK) - panic("Failed to set grant"); - - m.m_type = DL_WRITEV_S; - m.m_net_netdrv_dl_writev_s.count = 1; - m.m_net_netdrv_dl_writev_s.grant = nic->tx_iogrant; - - if (asynsend(nic->drv_ep, &m) != OK) - panic("asynsend to the driver failed!"); - nic->state = DRV_SENDING; - - debug_print("packet sent to driver"); - - return 1; -} - -static void nic_pkt_sent(struct nic * nic) -{ - debug_print("device /dev/%s", nic->name); - assert(nic->state != DRV_IDLE); - - /* packet has been sent, we are not intereted anymore */ - driver_tx_dequeue(nic); - /* - * Try to transmit the next packet. Failure means that no packet is - * enqueued and thus the device is entering idle state - */ - if (!driver_tx(nic)) - nic->state = DRV_IDLE; -} - -__unused static void print_pkt(unsigned char * pkt, int len) -{ - int i = 0; - - printf("--- PKT ---\n"); - - while (i < len) { - int x; - - for (x = 0; x < 8 && i < len; x++, i++) - printf("%02x ", pkt[i]); - - kputc(' '); - - for (x = 0; x < 8 && i < len; x++, i++) - printf("%02x ", pkt[i]); - - kputc('\n'); - } - - printf("--- PKT END ---\n"); -} - -static int raw_receive(struct sock_req *req, - struct pbuf *pbuf) -{ - struct pbuf * p; - unsigned int rem_len = req->size; - unsigned int written = 0; - int err; - - debug_print("user buffer size : %d\n", rem_len); - - for (p = pbuf; p && rem_len; p = p->next) { - size_t cp_len; - - cp_len = (rem_len < p->len) ? rem_len : p->len; - err = copy_to_user(req->endpt, p->payload, cp_len, - req->grant, written); - if (err != OK) - return err; - - written += cp_len; - rem_len -= cp_len; - } - - debug_print("copied %d bytes\n", written); - return written; -} - -int raw_socket_input(struct pbuf * pbuf, struct nic * nic) -{ - struct socket * sock; - struct pbuf * pbuf_new; - - if ((sock = nic->raw_socket) == NULL) - return 0; - - debug_print("socket num : %ld", get_sock_num(sock)); - - if (sock->flags & SOCK_FLG_OP_PENDING) { - int ret; - /* we are resuming a suspended operation */ - ret = raw_receive(&sock->req, pbuf); - - send_req_reply(&sock->req, ret); - sock->flags &= ~SOCK_FLG_OP_PENDING; - - if (ret > 0) - return 0; - } - - /* Do not enqueue more data than allowed */ - if (sock->recv_data_size > RAW_BUF_SIZE) { - return 0; - } - - /* - * nobody is waiting for the data or an error occured above, we enqueue - * the packet. We store a copy of this packet - */ - pbuf_new = pbuf_alloc(PBUF_RAW, pbuf->tot_len, PBUF_RAM); - if (pbuf_new == NULL) { - debug_print("LWIP : cannot allocated new pbuf\n"); - return 0; - } - - if (pbuf_copy(pbuf_new, pbuf) != ERR_OK) { - debug_print("LWIP : cannot copy pbuf\n"); - return 0; - } - - /* - * If we didn't managed to enqueue the packet we report it as not - * consumed - */ - if (sock_enqueue_data(sock, pbuf_new, pbuf_new->tot_len) != OK) { - pbuf_free(pbuf_new); - } - - return 0; -} - -static void nic_pkt_received(struct nic * nic, unsigned int size) -{ - assert(nic->netif.input); - -#if 0 - print_pkt((unsigned char *) nic->rx_pbuf->payload, 64 /*nic->rx_pbuf->len */); -#endif - - assert(nic->rx_pbuf->tot_len == nic->rx_pbuf->len); - nic->rx_pbuf->tot_len = nic->rx_pbuf->len = size - ETH_CRC_SIZE; - - nic->netif.input(nic->rx_pbuf, &nic->netif); - nic->rx_pbuf = NULL; - driver_setup_read(nic); -} - -void driver_request(message * m) -{ - struct nic * nic; - - if ((nic = lookup_nic_by_drv_ep(m->m_source)) == NULL) { - printf("LWIP : request from unknown driver %d\n", m->m_source); - return; - } - - switch (m->m_type) { - case DL_CONF_REPLY: - if (m->m_netdrv_net_dl_conf.stat == OK) - nic_up(nic, m); - break; - case DL_TASK_REPLY: - /* - if (!(m->m_netdrv_net_dl_task.flags & DL_PACK_SEND) && - !(m->m_netdrv_net_dl_task.flags & DL_PACK_RECV)) { - printf("void reply from driver\n"); - break; - } - */ - if (m->m_netdrv_net_dl_task.flags & DL_PACK_SEND) - nic_pkt_sent(nic); - if (m->m_netdrv_net_dl_task.flags & DL_PACK_RECV) - nic_pkt_received(nic, m->m_netdrv_net_dl_task.count); - break; - case DL_STAT_REPLY: - break; - default: - printf("LWIP : unexpected request %d from driver %d\n", - m->m_type, m->m_source); - } -} - -void driver_up(const char * label, endpoint_t ep) -{ - struct nic * nic; - - nic = lookup_nic_by_drv_name(label); - - if (nic) { - debug_print("LWIP : driver '%s' / %d is up for /dev/%s\n", - label, ep, nic->name); - nic->drv_ep = ep; - } else { - printf("LWIP : WARNING unexpected driver '%s' up event\n", - label); - return; - } - - nic->state = DRV_IDLE; - - /* - * FIXME - * - * We set the initial ip to 0.0.0.0 to make dhcpd broadcasing work - * at the very begining. dhcp should use raw socket but it is a little - * tricy in the current dhcp implementation - */ - if (!netif_add(&nic->netif, (ip_addr_t *) __UNCONST( &ip_addr_any), - &ip_addr_none, &ip_addr_none, nic, ethernetif_init, ethernet_input)) { - printf("LWIP : failed to add device /dev/%s\n", nic->name); - nic->drv_ep = NONE; - } - if (nic->is_default) - netif_set_default(&nic->netif); - - /* FIXME we support ethernet only, 2048 is safe */ - nic->tx_buffer = debug_malloc(2048); - if (nic->tx_buffer == NULL) - panic("Cannot allocate tx_buffer"); - /* When driver restarts, the rx_pbuf is likely ready to receive data - * from its previous instance. We free the buffer here, nobody depends - * on it. A new one is allocated when we send a new read request to the - * driver. - */ - if (nic->rx_pbuf) { - pbuf_free(nic->rx_pbuf); - nic->rx_pbuf = NULL; - } - - /* prepare the RX grant once and forever */ - if (cpf_setgrant_direct(nic->rx_iogrant, - nic->drv_ep, - (vir_bytes) &nic->rx_iovec, - 1 * sizeof(iovec_s_t), CPF_READ) != OK) - panic("Failed to set grant"); -} - -static void raw_recv_free(__unused void * data) -{ - pbuf_free((struct pbuf *) data); -} - -static int nic_op_close(struct socket * sock) -{ - struct nic * nic = (struct nic *)sock->data; - - debug_drv_print("socket %ld", get_sock_num(sock)); - - sock_dequeue_data_all(sock, raw_recv_free); - sock->ops = NULL; - - if (nic->raw_socket == sock) { - nic->raw_socket = NULL; - debug_drv_print("no active raw sock at %s", nic->name); - } - - return OK; -} - -static int nic_ioctl_set_conf(__unused struct socket * sock, - struct nic * nic, - endpoint_t endpt, - cp_grant_id_t grant) -{ - nwio_ipconf_t ipconf; - int err; - - err = copy_from_user(endpt, &ipconf, sizeof(ipconf), grant, 0); - if (err != OK) - return err; - - if (ipconf.nwic_flags & NWIC_IPADDR_SET) - netif_set_ipaddr(&nic->netif, - (ip_addr_t *)&ipconf.nwic_ipaddr); - if (ipconf.nwic_flags & NWIC_NETMASK_SET) - netif_set_netmask(&nic->netif, - (ip_addr_t *)&ipconf.nwic_netmask); - nic->flags = ipconf.nwic_flags; - if (nic->flags & NWEO_EN_BROAD) - nic->netif.flags |= NETIF_FLAG_BROADCAST; - - - return OK; -} - -static int nic_ioctl_get_conf(__unused struct socket * sock, - struct nic * nic, - endpoint_t endpt, - cp_grant_id_t grant) -{ - nwio_ipconf_t ipconf; - - ipconf.nwic_flags = nic->flags; - ipconf.nwic_ipaddr = nic->netif.ip_addr.addr; - ipconf.nwic_netmask = nic->netif.netmask.addr; - ipconf.nwic_mtu = nic->netif.mtu; - - return copy_to_user(endpt, &ipconf, sizeof(ipconf), grant, 0); -} - -static int nic_ioctl_set_gateway(__unused struct socket * sock, - struct nic * nic, - endpoint_t endpt, - cp_grant_id_t grant) -{ - nwio_route_t route; - int err; - - err = copy_from_user(endpt, &route, sizeof(route), grant, 0); - if (err != OK) - return err; - - netif_set_gw(&nic->netif, (ip_addr_t *)&route.nwr_gateway); - - return OK; -} - -static int nic_ioctl_get_ethstat(__unused struct socket * sock, - struct nic * nic, - endpoint_t endpt, - cp_grant_id_t grant) -{ - nwio_ethstat_t ethstat; - - debug_drv_print("device /dev/%s", nic->name); - /* - * The device is not up yet, there is nothing to report or it is not - * an ethernet device - */ - if (!nic->netif.flags & NETIF_FLAG_UP || - !(nic->netif.flags & (NETIF_FLAG_ETHERNET | - NETIF_FLAG_ETHARP))) { - printf("LWIP no such device FUCK\n"); - return ENODEV; - } - - memset(ðstat, 0, sizeof(ethstat)); - memcpy(ðstat.nwes_addr, nic->netif.hwaddr, 6); - - return copy_to_user(endpt, ðstat, sizeof(ethstat), grant, 0); -} - -static int nic_ioctl_set_ethopt(struct socket * sock, - struct nic * nic, - endpoint_t endpt, - cp_grant_id_t grant) -{ - int err; - nwio_ethopt_t ethopt; - - assert(nic); - - if (!sock) - return EINVAL; - - debug_drv_print("device /dev/%s", nic->name); - /* - * The device is not up yet, there is nothing to report or it is not - * an ethernet device - */ - if (!nic->netif.flags & NETIF_FLAG_UP || - !(nic->netif.flags & (NETIF_FLAG_ETHERNET | - NETIF_FLAG_ETHARP))) { - return ENODEV; - } - - err = copy_from_user(endpt, ðopt, sizeof(ethopt), grant, 0); - if (err != OK) - return err; - - /* we want to get data from this sock */ - if (ethopt.nweo_flags & NWEO_COPY) { - if (nic->raw_socket) - return EBUSY; - - nic->raw_socket = sock; - debug_drv_print("active raw sock %ld at %s", - get_sock_num(sock), nic->name); - } - - return OK; -} - -static int nic_do_ioctl(struct socket * sock, struct nic * nic, - struct sock_req * req) -{ - int r; - - debug_print("device /dev/%s req %c %ld %ld", - nic->name, - (unsigned char) (req->req >> 8), - req->req & 0xff, _MINIX_IOCTL_SIZE(req->req)); - - debug_drv_print("socket %ld", sock ? get_sock_num(sock) : -1); - - switch (req->req) { - case NWIOSIPCONF: - r = nic_ioctl_set_conf(sock, nic, req->endpt, req->grant); - break; - case NWIOGIPCONF: - r = nic_ioctl_get_conf(sock, nic, req->endpt, req->grant); - break; - case NWIOSIPOROUTE: - r = nic_ioctl_set_gateway(sock, nic, req->endpt, req->grant); - break; - case NWIOGETHSTAT: - r = nic_ioctl_get_ethstat(sock, nic, req->endpt, req->grant); - break; - case NWIOSETHOPT: - r = nic_ioctl_set_ethopt(sock, nic, req->endpt, req->grant); - break; - default: - r = ENOTTY; - } - - return r; -} - -int nic_default_ioctl(struct sock_req *req) -{ - struct nic * nic = lookup_nic_default(); - - if (nic == NULL) { - debug_print("No default nic, reporting error"); - return ENOTTY; - } - - return nic_do_ioctl(NULL, nic, req); -} - -static int nic_op_ioctl(struct socket * sock, struct sock_req * req, - __unused int blk) -{ - return nic_do_ioctl(sock, (struct nic *)sock->data, req); -} - -static int nic_op_read(struct socket * sock, struct sock_req * req, int blk) -{ - debug_drv_print("sock num %ld", get_sock_num(sock)); - - if (sock->recv_head) { - /* data available receive immeditely */ - - struct pbuf * pbuf; - int ret; - - pbuf = sock->recv_head->data; - - ret = raw_receive(req, pbuf); - - if (ret > 0) { - sock_dequeue_data(sock); - sock->recv_data_size -= pbuf->tot_len; - pbuf_free(pbuf); - } - return ret; - } else if (!blk) - return EAGAIN; - else { - /* store the request so we know how to reply */ - sock->req = *req; - /* operation is being processes */ - sock->flags |= SOCK_FLG_OP_PENDING; - - debug_print("no data to read, suspending"); - return EDONTREPLY; - } -} - -static int nic_op_write(struct socket * sock, struct sock_req * req, - __unused int blk) -{ - int ret; - struct pbuf * pbuf; - struct nic * nic = (struct nic *)sock->data; - - assert(nic); - debug_print("device %s data size %u", nic->name, req->size); - - pbuf = pbuf_alloc(PBUF_RAW, req->size, PBUF_RAM); - if (!pbuf) - return ENOMEM; - - if ((ret = copy_from_user(req->endpt, pbuf->payload, req->size, - req->grant, 0)) != OK) { - pbuf_free(pbuf); - return ret; - } - - if ((ret = nic->netif.linkoutput(&nic->netif, pbuf)) != ERR_OK) { - debug_print("raw linkoutput failed %d", ret); - ret = EIO; - } else - ret = req->size; - - pbuf_free(pbuf); - - return ret; -} - -static struct sock_ops nic_ops = { - .write = nic_op_write, - .read = nic_op_read, - .close = nic_op_close, - .ioctl = nic_op_ioctl, - .select = generic_op_select, - .select_reply = generic_op_select_reply -}; - -int nic_open(devminor_t minor) -{ - struct socket * sock; - - debug_print("device %d", minor); - - if (minor > MAX_DEVS || devices[minor].drv_ep == NONE) - return ENODEV; - - sock = get_unused_sock(); - - if (sock == NULL) - return ENODEV; - if (sock->ops != NULL) - return EBUSY; - - sock->ops = &nic_ops; - sock->select_ep = NONE; - sock->recv_data_size = 0; - sock->data = &devices[minor]; - - return get_sock_num(sock); -} - -static int driver_pkt_enqueue(struct packet_q ** head, - struct packet_q ** tail, - struct pbuf * pbuf) -{ - struct packet_q * pkt; - char * b; - - pkt = (struct packet_q *) malloc(sizeof(struct packet_q) + pbuf->tot_len); - if (!pkt) - return ENOMEM; - - pkt->next = NULL; - pkt->buf_len = pbuf->tot_len; - - for (b = pkt->buf; pbuf; pbuf = pbuf->next) { - memcpy(b, pbuf->payload, pbuf->len); - b += pbuf->len; - } - - if (*head == NULL) - *head = *tail = pkt; - else { - (*tail)->next = pkt; - *tail = pkt; - } - - return OK; -} - -int driver_tx_enqueue(struct nic * nic, struct pbuf * pbuf) -{ - debug_print("device /dev/%s", nic->name); - return driver_pkt_enqueue(&nic->tx_head, &nic->tx_tail, pbuf); -} - -static void driver_pkt_dequeue(struct packet_q ** head, - struct packet_q ** tail) -{ - struct packet_q * pkt; - - /* we always dequeue only if there is something to dequeue */ - assert(*head); - - pkt = *head; - - if ((*head = pkt->next) == NULL) - *tail = NULL; - - debug_free(pkt); -} - -void driver_tx_dequeue(struct nic * nic) -{ - debug_print("device /dev/%s", nic->name); - driver_pkt_dequeue(&nic->tx_head, &nic->tx_tail); -} - -struct packet_q * driver_tx_head(struct nic * nic) -{ - debug_print("device /dev/%s", nic->name); - - if (!nic->tx_head) - return NULL; - return nic->tx_head; -} diff --git a/minix/net/lwip/driver.h b/minix/net/lwip/driver.h deleted file mode 100644 index 6a7bca2a3..000000000 --- a/minix/net/lwip/driver.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef __LWIP_DRIVER_H_ -#define __LWIP_DRIVER_H_ - -#include -#include - -#include - -#define NIC_NAME_LEN 6 -#define DRV_NAME_LEN DS_MAX_KEYLEN - -#define TX_IOVEC_NUM 16 /* something the drivers assume */ - -struct packet_q { - struct packet_q * next; - unsigned int buf_len; - char buf[]; -}; - -#define DRV_IDLE 0 -#define DRV_SENDING 1 -#define DRV_RECEIVING 2 - -struct nic { - unsigned int flags; - char name[NIC_NAME_LEN]; - char drv_name[DRV_NAME_LEN]; - endpoint_t drv_ep; - int is_default; - int state; - cp_grant_id_t rx_iogrant; - iovec_s_t rx_iovec[1]; - struct pbuf * rx_pbuf; - cp_grant_id_t tx_iogrant; - iovec_s_t tx_iovec[TX_IOVEC_NUM]; - struct packet_q * tx_head; - struct packet_q * tx_tail; - void * tx_buffer; - struct netif netif; - unsigned int max_pkt_sz; - unsigned int min_pkt_sz; - struct socket * raw_socket; -}; - -int driver_tx_enqueue(struct nic * nic, struct pbuf * pbuf); -void driver_tx_dequeue(struct nic * nic); -struct packet_q * driver_tx_head(struct nic * nic); - -/* - * Transmit the next packet in the TX queue of this device. Returns 1 if - * success, 0 otherwise. - */ -int driver_tx(struct nic * nic); -int raw_socket_input(struct pbuf * pbuf, struct nic * nic); - -#endif /* __LWIP_DRIVER_H_ */ diff --git a/minix/net/lwip/eth.c b/minix/net/lwip/eth.c deleted file mode 100644 index 94a732ef6..000000000 --- a/minix/net/lwip/eth.c +++ /dev/null @@ -1,135 +0,0 @@ -/** - * @file - * Ethernet Interface Skeleton - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. 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. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -/* - * This file is a skeleton for developing Ethernet network interface - * drivers for lwIP. Add code to the low_level functions and do a - * search-and-replace for the word "ethernetif" to replace it with - * something that better describes your network interface. - */ - -#include -#include - -#include "lwip/opt.h" - -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/pbuf.h" -#include "lwip/sys.h" -#include -#include -#include - -#include -#include - -#include "proto.h" -#include "driver.h" - -static err_t low_level_output(__unused struct netif *netif, struct pbuf *pbuf) -{ - struct nic * nic; - - nic = (struct nic *) netif->state; - assert(&nic->netif == netif); - - debug_print("device /dev/%s", nic->name); - - if (driver_tx_enqueue(nic, pbuf) != OK) - return ERR_MEM; - - /* if the driver is idle, start transmitting the packet */ - if (nic->state == DRV_IDLE) { - if (!driver_tx(nic)) - return ERR_MEM; - } - - return ERR_OK; -} - -static void low_level_init(struct netif *netif) -{ - message m; - struct nic * nic = (struct nic *) netif->state; - - assert(nic); - - /* set MAC hardware address length */ - netif->hwaddr_len = ETHARP_HWADDR_LEN; - - /* maximum transfer unit */ - netif->mtu = 1500; - nic->max_pkt_sz = ETH_MAX_PACK_SIZE; - nic->min_pkt_sz = ETH_MIN_PACK_SIZE; - - /* device capabilities */ - netif->flags = NETIF_FLAG_ETHARP; - - m.m_net_netdrv_dl_conf.mode = DL_NOMODE; - if (nic->flags & NWEO_EN_BROAD) - m.m_net_netdrv_dl_conf.mode |= DL_BROAD_REQ; - if (nic->flags & NWEO_EN_MULTI) - m.m_net_netdrv_dl_conf.mode |= DL_MULTI_REQ; - if (nic->flags & NWEO_EN_PROMISC) - m.m_net_netdrv_dl_conf.mode |= DL_PROMISC_REQ; - - m.m_type = DL_CONF; - - if (asynsend(((struct nic *)netif->state)->drv_ep , &m) != OK) - printf("LWIP : ERROR cannot send DL_CONF to driver\n"); -} - - -err_t ethernetif_init(struct netif *netif) -{ - /* - * Initialize the snmp variables and counters inside the struct netif. - * The last argument should be replaced with your link speed, in units - * of bits per second. - NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS); - */ - - netif->output = etharp_output; - netif->linkoutput = low_level_output; - - /* initialize the hardware */ - low_level_init(netif); - - return ERR_OK; -} diff --git a/minix/net/lwip/inet_config.c b/minix/net/lwip/inet_config.c deleted file mode 100644 index 1f7009f45..000000000 --- a/minix/net/lwip/inet_config.c +++ /dev/null @@ -1,271 +0,0 @@ -/* -inet/inet_config.c - -Created: Nov 11, 1992 by Philip Homburg - -Modified: Apr 07, 2001 by Kees J. Bot - Read the configuration file and fill in the xx_conf[] arrays. - -Copyright 1995 Philip Homburg -*/ - -#define _POSIX_SOURCE 1 -#define _NETBSD_SOURCE 1 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "inet_config.h" - -#include "proto.h" - -struct eth_conf eth_conf[IP_PORT_MAX]; -struct psip_conf psip_conf[IP_PORT_MAX]; -struct ip_conf ip_conf[IP_PORT_MAX]; -struct tcp_conf tcp_conf[IP_PORT_MAX]; -struct udp_conf udp_conf[IP_PORT_MAX]; -dev_t ip_dev; - -int eth_conf_nr; -int psip_conf_nr; -int ip_conf_nr; -int tcp_conf_nr; -int udp_conf_nr; - -int ip_forward_directed_bcast= 0; /* Default is off */ - -static int ifdefault= -1; /* Default network interface. */ - -__dead -static void fatal(const char *label) -{ - printf("init: %s: %s\n", label, strerror(errno)); - exit(1); -} - -static void check_mknod(const char *device, mode_t mode, int minor) -/* Check if a device exists with the proper device number. */ -{ - dev_t dev; - - dev= makedev(major(ip_dev), minor); - - unlink(device); - if (mknod(device, S_IFCHR | mode, dev) < 0) fatal(device); - printf("mknod %s c %d %d\n", device, major(ip_dev), minor); -} - -static int cfg_fd; -static char word[16]; -static unsigned char line[256], *lineptr; -static unsigned int linenr; - -static __dead void error(void) -{ - printf("inet: error on line %u\n", linenr); - exit(1); -} - -static int nextline(void) -{ - /* Read a line from the configuration file, to be used by subsequent - * token() calls. Skip empty lines, and lines where the first character - * after leading "whitespace" is '#'. The last line of the file need - * not be terminated by a newline. Return 1 if a line was read in - * successfully, and 0 on EOF or error. - */ - unsigned char *lp, c; - int r, skip; - - lineptr = lp = line; - linenr++; - skip = -1; - - while ((r = read(cfg_fd, &c, 1)) == 1) { - if (c == '\n') { - if (skip == 0) - break; - - linenr++; - skip = -1; - continue; - } - - if (skip == -1 && c > ' ') - skip = (c == '#'); - - if (skip == 0 && lp < (unsigned char *) line + sizeof(line)-1) - *lp++ = c; - } - - *lp = 0; - return (r == 1 || lp != line); -} - -static void token(int need) -{ - /* Read a word from the configuration line. Return a null string on - * EOL. Return a punctuation as a one character word. If 'need' is - * true then an actual word is expected at this point, so err out if - * not. - */ - unsigned char *wp; - static unsigned char c= '\n'; - - wp= (unsigned char *) word; - *wp = 0; - - while (c <= ' ') { - if (*lineptr == 0) { - if (need) error(); - return; - } - c = *lineptr++; - } - - do { - if (wp < (unsigned char *) word + sizeof(word)-1) *wp++ = c; - c = (*lineptr != 0) ? *lineptr++ : ' '; - if (word[0] == ';' || word[0] == '{' || word[0] == '}') { - if (need) error(); - break; - } - } while (c > ' ' && c != ';' && c != '{' && c != '}'); - *wp = 0; -} - -void inet_read_conf(void) -{ - int ifno, enable; - struct stat st; - - { static int first= 1; - if (!first) - panic(( "LWIP : read_conf: called a second time" )); - first= 0; -#if 0 - *(u8_t *)0 = 0xcc; /* INT 3 */ -#endif - } - - - /* Open the configuration file. */ - if ((cfg_fd= open(PATH_INET_CONF, O_RDONLY)) == -1) - fatal(PATH_INET_CONF); - - while (nextline()) { - token(1); - char drv_name[128]; - unsigned int instance; - - if (strncmp(word, "eth", 3) == 0) { - - ifno = strtol(word+3, NULL, 10); - token(1); -#if 1 - strncpy(drv_name, word, 128); -#else - sprintf(drv_name, "%s_debug", word); -#endif - token(1); - instance = strtol(word, NULL, 10); - } else { - printf("inet: Unknown device '%s'\n", word); - error(); - } - - enable= 7; /* 1 = IP, 2 = TCP, 4 = UDP */ - - token(0); - if (word[0] == '{') { - token(0); - while (word[0] != '}') { - if (strcmp(word, "default") == 0) { - if (ifdefault != -1) { - printf( - "inet: ip%d and ip%d can't both be default\n", - ifdefault, ifno); - error(); - } - ifdefault= ifno; - token(0); - } else - if (strcmp(word, "no") == 0) { - token(1); - if (strcmp(word, "ip") == 0) { - enable= 0; - } else - if (strcmp(word, "tcp") == 0) { - enable &= ~2; - } else - if (strcmp(word, "udp") == 0) { - enable &= ~4; - } else { - printf( - "inet: Can't do 'no %s'\n", - word); - exit(1); - } - token(0); - } else { - printf("inet: Unknown option '%s'\n", - word); - exit(1); - } - if (word[0] == ';') token(0); - else - if (word[0] != '}') error(); - } - token(0); - } - if (word[0] != ';' && word[0] != 0) error(); - - nic_assign_driver("eth", ifno, drv_name, instance, ifdefault == ifno); - } - - if (ifdefault == -1) { - printf("inet: No networks or no default network defined\n"); - exit(1); - } - - /* Set umask 0 so we can creat mode 666 devices. */ - (void) umask(0); - - /* See what the device number of /dev/ip is. That's what we - * used last time for the network devices, so we keep doing so. - */ - if (stat("/dev/ip", &st) < 0) fatal("/dev/ip"); - ip_dev= st.st_rdev; - - /* create protocol devices */ - check_mknod("/dev/ip", 0600, SOCK_TYPE_IP); - check_mknod("/dev/tcp", 0666, SOCK_TYPE_TCP); - check_mknod("/dev/udp", 0666, SOCK_TYPE_UDP); - - /* - * create hw devices, to configure ip we need also ip devices for each - */ - check_mknod("/dev/ip0", 0600, SOCK_TYPES + 0); - check_mknod("/dev/eth0", 0600, SOCK_TYPES + 0); - - check_mknod("/dev/ip1", 0600, SOCK_TYPES + 1); - check_mknod("/dev/eth1", 0600, SOCK_TYPES + 1); - - check_mknod("/dev/ip2", 0600, SOCK_TYPES + 2); - check_mknod("/dev/eth2", 0600, SOCK_TYPES + 2); - - check_mknod("/dev/ip3", 0600, SOCK_TYPES + 3); - check_mknod("/dev/eth3", 0600, SOCK_TYPES + 3); - - check_mknod("/dev/ip4", 0600, SOCK_TYPES + 4); - check_mknod("/dev/eth4", 0600, SOCK_TYPES + 4); - -} diff --git a/minix/net/lwip/inet_config.h b/minix/net/lwip/inet_config.h deleted file mode 100644 index 9608268b9..000000000 --- a/minix/net/lwip/inet_config.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -inet/inet_config.h - -Created: Nov 11, 1992 by Philip Homburg - -Defines values for configurable parameters. The structure definitions for -configuration information are also here. - -Copyright 1995 Philip Homburg -*/ - -#ifndef INET__INET_CONFIG_H -#define INET__INET_CONFIG_H - -/* Inet configuration file. */ -#define PATH_INET_CONF "/etc/inet.conf" - -#define IP_PORT_MAX 32 /* Up to this many network devices */ -extern int eth_conf_nr; /* Number of ethernets */ -extern int psip_conf_nr; /* Number of Pseudo IP networks */ -extern int ip_conf_nr; /* Number of configured IP layers */ -extern int tcp_conf_nr; /* Number of configured TCP layers */ -extern int udp_conf_nr; /* Number of configured UDP layers */ - -extern dev_t ip_dev; /* Device number of /dev/ip */ - -struct eth_conf -{ - char *ec_label; /* Process label name if nonnull */ - u8_t ec_port; /* Ethernet port for VLAN if label == NULL */ - u8_t ec_ifno; /* Interface number of /dev/eth* */ - u16_t ec_vlan; /* VLAN number of this net if label == NULL */ -}; -#define eth_is_vlan(ecp) ((ecp)->ec_label == NULL) - -struct psip_conf -{ - u8_t pc_ifno; /* Interface number of /dev/psip* */ -}; - -struct ip_conf -{ - u8_t ic_devtype; /* Underlying device type: Ethernet / PSIP */ - u8_t ic_port; /* Port of underlying device */ - u8_t ic_ifno; /* Interface number of /dev/ip*, tcp*, udp* */ -}; - -struct tcp_conf -{ - u8_t tc_port; /* IP port number */ -}; - -struct udp_conf -{ - u8_t uc_port; /* IP port number */ -}; - -/* Types of networks. */ -#define NETTYPE_ETH 1 -#define NETTYPE_PSIP 2 - -/* To compute the minor device number for a device on an interface. */ -#define if2minor(ifno, dev) (1 + (ifno) * 8 + (dev)) - -#define IPSTAT_DEV "/dev/ipstat" -#define IPSTAT_MODE 0666 /* Is this right? What about just setuid apps */ -#define IPSTAT_MINOR 0 /* Minor number of /dev/ipstat */ - -/* Offsets of the minor device numbers within a group per interface. */ -#define ETH_DEV_OFF 0 -#define PSIP_DEV_OFF 0 -#define IP_DEV_OFF 1 -#define TCP_DEV_OFF 2 -#define UDP_DEV_OFF 3 - -extern struct eth_conf eth_conf[IP_PORT_MAX]; -extern struct psip_conf psip_conf[IP_PORT_MAX]; -extern struct ip_conf ip_conf[IP_PORT_MAX]; -extern struct tcp_conf tcp_conf[IP_PORT_MAX]; -extern struct udp_conf udp_conf[IP_PORT_MAX]; -void read_conf(void); -void *alloc(size_t size); - -/* Options */ -extern int ip_forward_directed_bcast; - -#endif /* INET__INET_CONFIG_H */ - -/* - * $PchId: inet_config.h,v 1.10 2003/08/21 09:24:33 philip Exp $ - */ diff --git a/minix/net/lwip/lwip.c b/minix/net/lwip/lwip.c deleted file mode 100644 index 649ad038e..000000000 --- a/minix/net/lwip/lwip.c +++ /dev/null @@ -1,291 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "proto.h" - -#include -#include -#include -#include -#include -#include - -static minix_timer_t tcp_ftmr, tcp_stmr, arp_tmr; -static int arp_ticks, tcp_fticks, tcp_sticks; - -static struct netif * netif_lo; - -extern struct sock_ops sock_udp_ops; -extern struct sock_ops sock_tcp_ops; -extern struct sock_ops sock_raw_ip_ops; - -static void sys_init(void) -{ -} - -static void arp_watchdog(int arg __unused) -{ - etharp_tmr(); - set_timer(&arp_tmr, arp_ticks, arp_watchdog, 0); -} - -static void tcp_fwatchdog(int arg __unused) -{ - tcp_fasttmr(); - set_timer(&tcp_ftmr, tcp_fticks, tcp_fwatchdog, 0); -} - -static void tcp_swatchdog(int arg __unused) -{ - tcp_slowtmr(); - set_timer(&tcp_ftmr, tcp_sticks, tcp_swatchdog, 0); -} - -static int sef_cb_init_fresh(__unused int type, __unused sef_init_info_t *info) -{ - int err; - unsigned int hz; - - nic_init_all(); - inet_read_conf(); - - /* init lwip library */ - stats_init(); - sys_init(); - mem_init(); - memp_init(); - pbuf_init(); - - hz = sys_hz(); - - arp_ticks = ARP_TMR_INTERVAL / (1000 / hz); - tcp_fticks = TCP_FAST_INTERVAL / (1000 / hz); - tcp_sticks = TCP_SLOW_INTERVAL / (1000 / hz); - - etharp_init(); - - set_timer(&arp_tmr, arp_ticks, arp_watchdog, 0); - set_timer(&tcp_ftmr, tcp_fticks, tcp_fwatchdog, 0); - set_timer(&tcp_stmr, tcp_sticks, tcp_swatchdog, 0); - - netif_init(); - netif_lo = netif_find(__UNCONST("lo0")); - - /* Read configuration. */ -#if 0 - nw_conf(); - - /* Get a random number */ - timerand= 1; - fd = open(RANDOM_DEV_NAME, O_RDONLY | O_NONBLOCK); - if (fd != -1) - { - err= read(fd, randbits, sizeof(randbits)); - if (err == sizeof(randbits)) - timerand= 0; - else - { - printf("inet: unable to read random data from %s: %s\n", - RANDOM_DEV_NAME, err == -1 ? strerror(errno) : - err == 0 ? "EOF" : "not enough data"); - } - close(fd); - } - else - { - printf("inet: unable to open random device %s: %s\n", - RANDOM_DEV_NAME, strerror(errno)); - } - if (timerand) - { - printf("inet: using current time for random-number seed\n"); - err= gettimeofday(&tv, NULL); - if (err == -1) - { - printf("sysutime failed: %s\n", strerror(errno)); - exit(1); - } - memcpy(randbits, &tv, sizeof(tv)); - } - init_rand256(randbits); -#endif - - /* Subscribe to driver events for network drivers. */ - if ((err = ds_subscribe("drv\\.net\\..*", - DSF_INITIAL | DSF_OVERWRITE)) != OK) - panic(("inet: can't subscribe to driver events")); - - /* Announce we are up. LWIP announces its presence to VFS just like - * any other character driver. - */ - chardriver_announce(); - - /* Register net.route RMIB subtree with the MIB service. */ - rtinfo_init(); - - return(OK); -} - -static void sef_local_startup(void) -{ - /* Register init callbacks. */ - sef_setcb_init_fresh(sef_cb_init_fresh); - sef_setcb_init_restart(sef_cb_init_fresh); - - /* Let SEF perform startup. */ - sef_startup(); -} - -static void ds_event(void) -{ - char key[DS_MAX_KEYLEN]; - const char *driver_prefix = "drv.net."; - char *label; - u32_t value; - int type; - endpoint_t owner_endpoint; - int r; - int prefix_len; - - prefix_len = strlen(driver_prefix); - - /* We may get one notification for multiple updates from DS. Get events - * and owners from DS, until DS tells us that there are no more. - */ - while ((r = ds_check(key, &type, &owner_endpoint)) == OK) { - r = ds_retrieve_u32(key, &value); - if(r != OK) { - printf("LWIP : ds_event: ds_retrieve_u32 failed\n"); - return; - } - - /* Only check for network driver up events. */ - if(strncmp(key, driver_prefix, prefix_len) - || value != DS_DRIVER_UP) { - return; - } - - /* The driver label comes after the prefix. */ - label = key + strlen(driver_prefix); - - /* A driver is (re)started. */ - driver_up(label, owner_endpoint); - } - - if(r != ENOENT) - printf("LWIP : ds_event: ds_check failed: %d\n", r); -} - -static void netif_poll_lo(void) -{ - if (netif_lo == NULL) - return; - - while (netif_lo->loop_first) - netif_poll(netif_lo); -} - -int socket_open(devminor_t minor) -{ - struct sock_ops * ops; - struct socket * sock; - int ret = OK; - - switch (minor) { - case SOCK_TYPE_TCP: - ops = &sock_tcp_ops; - break; - case SOCK_TYPE_UDP: - ops = &sock_udp_ops; - break; - case SOCK_TYPE_IP: - ops = &sock_raw_ip_ops; - break; - default: - if (minor - SOCK_TYPES < MAX_DEVS) - return nic_open(minor - SOCK_TYPES); - - printf("LWIP unknown socket type %d\n", minor); - return EINVAL; - } - - sock = get_unused_sock(); - if (!sock) { - printf("LWIP : no free socket\n"); - return EAGAIN; - } - - sock->ops = ops; - sock->select_ep = NONE; - sock->recv_data_size = 0; - - if (sock->ops && sock->ops->open) - ret = sock->ops->open(sock); - - if (ret == OK) { - debug_print("new socket %ld", get_sock_num(sock)); - ret = get_sock_num(sock); - } else { - debug_print("failed %d", ret); - /* FIXME: shouldn't sock be freed now? */ - } - return ret; -} - -int main(__unused int argc, __unused char ** argv) -{ - sef_local_startup(); - - for(;;) { - int err, ipc_status; - message m; - - netif_poll_lo(); - - mq_process(); - - if ((err = sef_receive_status(ANY, &m, &ipc_status)) != OK) { - printf("LWIP : sef_receive_status errr %d\n", err); - continue; - } - - if (m.m_source == VFS_PROC_NR) - socket_request(&m, ipc_status); - else if (is_ipc_notify(ipc_status)) { - switch (m.m_source) { - case CLOCK: - expire_timers(m.m_notify.timestamp); - break; - case DS_PROC_NR: - ds_event(); - break; - case PM_PROC_NR: - panic("LWIP : unhandled event from PM"); - break; - default: - printf("LWIP : unexpected notify from %d\n", - m.m_source); - continue; - } - } else if (m.m_source == MIB_PROC_NR) - rmib_process(&m, ipc_status); - else - /* all other request can be from drivers only */ - driver_request(&m); - } - - return 0; -} diff --git a/minix/net/lwip/lwip.conf b/minix/net/lwip/lwip.conf deleted file mode 100644 index 4586fe61b..000000000 --- a/minix/net/lwip/lwip.conf +++ /dev/null @@ -1,5 +0,0 @@ -service lwip -{ - uid 0; -}; - diff --git a/minix/net/lwip/proto.h b/minix/net/lwip/proto.h deleted file mode 100644 index 35ece8eed..000000000 --- a/minix/net/lwip/proto.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef __LWIP_PROTO_H__ -#define __LWIP_PROTO_H__ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#if 0 -#define debug_print(str, ...) printf("LWIP %s:%d : " str "\n", \ - __func__, __LINE__, ##__VA_ARGS__) -#else -#define debug_print(...) -#endif - -/* driver .c */ -void nic_assign_driver(const char * dev_type, - unsigned int dev_num, - const char * driver_name, - unsigned int instance, - int is_default); -struct nic *nic_get(int); -void nic_init_all(void); -void driver_request(message * m); -void driver_up(const char * label, endpoint_t ep); -/* opens a raw NIC socket */ -int nic_open(devminor_t minor); -int nic_default_ioctl(struct sock_req *req); - -/* inet_config.c */ -void inet_read_conf(void); - -/* eth.c */ -err_t ethernetif_init(struct netif *netif); - -static inline int copy_from_user(endpoint_t proc, - void * dst_ptr, - size_t size, - cp_grant_id_t gid, - vir_bytes offset) -{ - return sys_safecopyfrom(proc, gid, offset, (vir_bytes)dst_ptr, size); -} - -static inline int copy_to_user(endpoint_t proc, - void * src_ptr, - size_t size, - cp_grant_id_t gid, - vir_bytes offset) -{ - return sys_safecopyto(proc, gid, offset, (vir_bytes)src_ptr, size); -} - -/* rtinfo.c */ -void rtinfo_init(void); - -#endif /* __LWIP_PROTO_H__ */ diff --git a/minix/net/lwip/raw_ip.c b/minix/net/lwip/raw_ip.c deleted file mode 100644 index c719653d2..000000000 --- a/minix/net/lwip/raw_ip.c +++ /dev/null @@ -1,349 +0,0 @@ -#include - -#include -#include -#include - -#include -#include - -#include -#include "proto.h" - -#define RAW_IP_BUF_SIZE (32 << 10) - -#define sock_alloc_buf(s) debug_malloc(s) -#define sock_free_buf(x) debug_free(x) - -struct raw_ip_recv_data { - ip_addr_t ip; - struct pbuf * pbuf; -}; - -#define raw_ip_recv_alloc() debug_malloc(sizeof(struct raw_ip_recv_data)) - -static void raw_ip_recv_free(void * data) -{ - if (((struct raw_ip_recv_data *)data)->pbuf) - pbuf_free(((struct raw_ip_recv_data *)data)->pbuf); - debug_free(data); -} - - -static int raw_ip_op_open(struct socket * sock) -{ - debug_print("socket num %ld", get_sock_num(sock)); - - if (!(sock->buf = sock_alloc_buf(RAW_IP_BUF_SIZE))) { - return ENOMEM; - } - sock->buf_size = RAW_IP_BUF_SIZE; - - return OK; -} - -static void raw_ip_close(struct socket * sock) -{ - /* deque and free all enqueued data before closing */ - sock_dequeue_data_all(sock, raw_ip_recv_free); - - if (sock->pcb) - raw_remove(sock->pcb); - if (sock->buf) - sock_free_buf(sock->buf); - - /* mark it as unused */ - sock->ops = NULL; -} - -static int raw_ip_op_close(struct socket * sock) -{ - debug_print("socket num %ld", get_sock_num(sock)); - - raw_ip_close(sock); - - return OK; -} - -static int raw_ip_do_receive(struct sock_req *req, - struct pbuf *pbuf) -{ - struct pbuf * p; - size_t rem_len = req->size; - unsigned int written = 0, hdr_sz = 0; - int err; - - debug_print("user buffer size : %u\n", rem_len); - - for (p = pbuf; p && rem_len; p = p->next) { - size_t cp_len; - - cp_len = (rem_len < p->len) ? rem_len : p->len; - err = copy_to_user(req->endpt, p->payload, cp_len, req->grant, - hdr_sz + written); - - if (err != OK) - return err; - - written += cp_len; - rem_len -= cp_len; - } - - debug_print("copied %d bytes\n", written + hdr_sz); - return written + hdr_sz; -} - -static u8_t raw_ip_op_receive(void *arg, - __unused struct raw_pcb *pcb, - struct pbuf *pbuf, - ip_addr_t *addr) -{ - struct socket * sock = (struct socket *) arg; - struct raw_ip_recv_data * data; - int ret; - - debug_print("socket num : %ld addr : %x\n", - get_sock_num(sock), (unsigned int) addr->addr); - - if (sock->flags & SOCK_FLG_OP_PENDING) { - /* we are resuming a suspended operation */ - ret = raw_ip_do_receive(&sock->req, pbuf); - - send_req_reply(&sock->req, ret); - sock->flags &= ~SOCK_FLG_OP_PENDING; - - if (ret > 0) { - if (sock->usr_flags & NWIO_EXCL) { - pbuf_free(pbuf); - return 1; - } else - return 0; - } - } - - /* Do not enqueue more data than allowed */ - if (sock->recv_data_size > RAW_IP_BUF_SIZE) - return 0; - - /* - * nobody is waiting for the data or an error occured above, we enqueue - * the packet - */ - if (!(data = raw_ip_recv_alloc())) { - return 0; - } - - data->ip = *addr; - if (sock->usr_flags & NWIO_EXCL) { - data->pbuf = pbuf; - ret = 1; - } else { - /* we store a copy of this packet */ - data->pbuf = pbuf_alloc(PBUF_RAW, pbuf->tot_len, PBUF_RAM); - if (data->pbuf == NULL) { - debug_print("LWIP : cannot allocated new pbuf\n"); - raw_ip_recv_free(data); - return 0; - } - - if (pbuf_copy(data->pbuf, pbuf) != ERR_OK) { - debug_print("LWIP : cannot copy pbuf\n"); - raw_ip_recv_free(data); - return 0; - } - - ret = 0; - } - - /* - * If we didn't managed to enqueue the packet we report it as not - * consumed - */ - if (sock_enqueue_data(sock, data, data->pbuf->tot_len) != OK) { - raw_ip_recv_free(data); - ret = 0; - } - - return ret; -} - -static int raw_ip_op_read(struct socket * sock, struct sock_req * req, int blk) -{ - debug_print("socket num %ld", get_sock_num(sock)); - - if (sock->pcb == NULL) - return EIO; - - if (sock->recv_head) { - /* data available receive immeditely */ - - struct raw_ip_recv_data * data; - int ret; - - data = (struct raw_ip_recv_data *) sock->recv_head->data; - - ret = raw_ip_do_receive(req, data->pbuf); - - if (ret > 0) { - sock_dequeue_data(sock); - sock->recv_data_size -= data->pbuf->tot_len; - raw_ip_recv_free(data); - } - return ret; - } else if (!blk) - return EAGAIN; - else { - /* store the request so we know how to reply */ - sock->req = *req; - /* operation is being processes */ - sock->flags |= SOCK_FLG_OP_PENDING; - - debug_print("no data to read, suspending"); - return EDONTREPLY; - } -} - -static int raw_ip_op_write(struct socket * sock, struct sock_req * req, - __unused int blk) -{ - int ret; - struct pbuf * pbuf; - struct ip_hdr * ip_hdr; - - debug_print("socket num %ld data size %u", - get_sock_num(sock), req->size); - - if (sock->pcb == NULL) - return EIO; - - if (req->size > sock->buf_size) - return ENOMEM; - - pbuf = pbuf_alloc(PBUF_LINK, req->size, PBUF_RAM); - if (!pbuf) - return ENOMEM; - - if ((ret = copy_from_user(req->endpt, pbuf->payload, req->size, - req->grant, 0)) != OK) { - pbuf_free(pbuf); - return ret; - } - - ip_hdr = (struct ip_hdr *) pbuf->payload; - if (pbuf_header(pbuf, -IP_HLEN)) { - pbuf_free(pbuf); - return EIO; - } - - if ((ret = raw_sendto((struct raw_pcb *)sock->pcb, pbuf, - (ip_addr_t *) &ip_hdr->dest)) != OK) { - debug_print("raw_sendto failed %d", ret); - ret = EIO; - } else - ret = req->size; - - - pbuf_free(pbuf); - - return ret; -} - -static int raw_ip_set_opt(struct socket * sock, endpoint_t endpt, - cp_grant_id_t grant) -{ - int err; - nwio_ipopt_t ipopt; - struct raw_pcb * pcb; - - err = copy_from_user(endpt, &ipopt, sizeof(ipopt), grant, 0); - - if (err != OK) - return err; - - debug_print("ipopt.nwio_flags = 0x%x", ipopt.nwio_flags); - debug_print("ipopt.nwio_proto = 0x%x", ipopt.nwio_proto); - debug_print("ipopt.nwio_rem = 0x%x", - (unsigned int) ipopt.nwio_rem); - - if (sock->pcb == NULL) { - if (!(pcb = raw_new(ipopt.nwio_proto))) { - raw_ip_close(sock); - return ENOMEM; - } - - sock->pcb = pcb; - } else - pcb = (struct raw_pcb *) sock->pcb; - - if (pcb->protocol != ipopt.nwio_proto) { - debug_print("conflicting ip socket protocols\n"); - return EINVAL; - } - - sock->usr_flags = ipopt.nwio_flags; - -#if 0 - if (raw_bind(pcb, (ip_addr_t *)&ipopt.nwio_rem) == ERR_USE) { - raw_ip_close(sock); - return EADDRINUSE; - } -#endif - - /* register a receive hook */ - raw_recv((struct raw_pcb *) sock->pcb, raw_ip_op_receive, sock); - - return OK; -} - -static int raw_ip_get_opt(struct socket * sock, endpoint_t endpt, - cp_grant_id_t grant) -{ - nwio_ipopt_t ipopt; - struct raw_pcb * pcb = (struct raw_pcb *) sock->pcb; - - assert(pcb); - - ipopt.nwio_rem = pcb->remote_ip.addr; - ipopt.nwio_flags = sock->usr_flags; - - return copy_to_user(endpt, &ipopt, sizeof(ipopt), grant, 0); -} - -static int raw_ip_op_ioctl(struct socket * sock, struct sock_req * req, - __unused int blk) -{ - int r; - - debug_print("socket num %ld req %c %ld %ld", - get_sock_num(sock), - (unsigned char) (req->req >> 8), - req->req & 0xff, - _MINIX_IOCTL_SIZE(req->req)); - - switch (req->req) { - case NWIOSIPOPT: - r = raw_ip_set_opt(sock, req->endpt, req->grant); - break; - case NWIOGIPOPT: - r = raw_ip_get_opt(sock, req->endpt, req->grant); - break; - default: - /* - * /dev/ip can be also accessed as a default device to be - * configured - */ - r = nic_default_ioctl(req); - } - - return r; -} - -struct sock_ops sock_raw_ip_ops = { - .open = raw_ip_op_open, - .close = raw_ip_op_close, - .read = raw_ip_op_read, - .write = raw_ip_op_write, - .ioctl = raw_ip_op_ioctl, - .select = generic_op_select, - .select_reply = generic_op_select_reply -}; diff --git a/minix/net/lwip/rtinfo.c b/minix/net/lwip/rtinfo.c deleted file mode 100644 index add6609a6..000000000 --- a/minix/net/lwip/rtinfo.c +++ /dev/null @@ -1,397 +0,0 @@ -/* - * Mock net.route sysctl(2) subtree implementation using RMIB. This code - * serves as a temporary bridge to allow libc to switch from the original, - * native MINIX3 getifaddrs(3) to the NetBSD getifaddrs(3). As such, it - * implements only a small subset of NetBSD's full net.route functionality, - * although also more than needed only to imitate the MINIX3 getifaddrs(3). - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "proto.h" -#include "driver.h" - -/* Max. number of bytes for a full sockaddr_dl structure, including data. */ -#define SDL_BUFSIZE (sizeof(struct sockaddr_dl) + 32) - -static const char padbuf[RT_ROUNDUP(0)] = { 0 }; - -/* - * Compute the length for, and possibly copy out, an interface information or - * interface address record with an associated set of zero or more routing - * table addresses. The addresses are padded as necessary. Store the full - * record length and the address bitmap before copying out the entire record. - */ -static ssize_t -copyout_rta(void * hdr, size_t size, u_short * msglen, int * addrs, - void * rta_map[RTAX_MAX], size_t rta_len[RTAX_MAX], - struct rmib_oldp * oldp, ssize_t off) -{ - iovec_t iov[1 + RTAX_MAX * 2]; - size_t len, total, padlen; - unsigned int i, iovcnt; - int mask; - - iovcnt = 0; - iov[iovcnt].iov_addr = (vir_bytes)hdr; - iov[iovcnt++].iov_size = size; - - total = size; - mask = 0; - - /* - * Any addresses in the given map should be stored in the numbering - * order of the map. - */ - for (i = 0; i < RTAX_MAX; i++) { - if (rta_map[i] == NULL) - continue; - - assert(iovcnt < __arraycount(iov)); - iov[iovcnt].iov_addr = (vir_bytes)rta_map[i]; - iov[iovcnt++].iov_size = len = rta_len[i]; - - padlen = RT_ROUNDUP(len) - len; - if (padlen > 0) { - assert(iovcnt < __arraycount(iov)); - iov[iovcnt].iov_addr = (vir_bytes)padbuf; - iov[iovcnt++].iov_size = padlen; - } - - total += len + padlen; - mask |= (1 << i); - } - - /* If only the length was requested, return it now. */ - if (oldp == NULL) - return total; - - /* - * Casting 'hdr' would violate C99 strict aliasing rules, so store the - * computed header values through direct pointers. Bah. - */ - *msglen = total; - *addrs = mask; - - return rmib_vcopyout(oldp, off, iov, iovcnt); -} - -/* - * Compute the length for, and possibly generate, a sockaddr_dl structure for - * the given interface. The complication here is that the structure contains - * various field packed together dynamically, making it variable sized. - */ -static size_t -make_sdl(const struct nic * nic, int ndx, char * buf, size_t max) -{ - struct sockaddr_dl sdl; - size_t hdrlen, namelen, addrlen, padlen, len; - - namelen = strlen(nic->name); - addrlen = sizeof(nic->netif.hwaddr); - - /* - * Compute the unpadded and padded length of the structure. We pad the - * structure ourselves here, even though the caller will otherwise pad - * it later, because it is easy to do so and saves on a vector element. - */ - hdrlen = offsetof(struct sockaddr_dl, sdl_data); - len = hdrlen + namelen + addrlen; - padlen = RT_ROUNDUP(len) - len; - assert(len + padlen <= max); - - /* If we are asked not to generate the actual data, stop here. */ - if (buf == NULL) - return len + padlen; - - /* - * Fill the sockaddr_dl structure header. The C99 strict aliasing - * rules prevent us from filling 'buf' through a pointer structure - * directly. - */ - memset(&sdl, 0, hdrlen); - sdl.sdl_len = len; - sdl.sdl_family = AF_LINK; - sdl.sdl_index = ndx; - sdl.sdl_type = IFT_ETHER; - sdl.sdl_nlen = namelen; - sdl.sdl_alen = addrlen; - sdl.sdl_slen = 0; - - /* - * Generate the full sockaddr_dl structure in the given buffer. These - * memory sizes are typically small, so the extra memory copies are not - * too expensive. The advantage of generating a single sockaddr_dl - * structure buffer is that we can use copyout_rta() on it. - */ - memcpy(buf, &sdl, hdrlen); - if (namelen > 0) - memcpy(&buf[hdrlen], nic->name, namelen); - if (addrlen > 0) - memcpy(&buf[hdrlen + namelen], nic->netif.hwaddr, addrlen); - if (padlen > 0) - memset(&buf[len], 0, padlen); - - return len + padlen; -} - -/* - * Compute the length for, and possibly generate, an interface information - * record for the given interface. - */ -static ssize_t -gen_ifm(const struct nic * nic, int ndx, int is_up, struct rmib_oldp * oldp, - ssize_t off) -{ - struct if_msghdr ifm; - char buf[SDL_BUFSIZE]; - void *rta_map[RTAX_MAX]; - size_t rta_len[RTAX_MAX], size; - - if (oldp != NULL) { - memset(&ifm, 0, sizeof(ifm)); - ifm.ifm_version = RTM_VERSION; - ifm.ifm_type = RTM_IFINFO; - ifm.ifm_flags = (is_up) ? (IFF_UP | IFF_RUNNING) : 0; - ifm.ifm_index = ndx; - ifm.ifm_data.ifi_type = IFT_ETHER; - /* TODO: other ifm_flags, other ifm_data fields, etc. */ - } - - /* - * Note that we add padding even in this case, to ensure that the - * following structures are properly aligned as well. - */ - size = make_sdl(nic, ndx, (oldp != NULL) ? buf : NULL, sizeof(buf)); - - memset(rta_map, 0, sizeof(rta_map)); - rta_map[RTAX_IFP] = buf; - rta_len[RTAX_IFP] = size; - - return copyout_rta(&ifm, sizeof(ifm), &ifm.ifm_msglen, &ifm.ifm_addrs, - rta_map, rta_len, oldp, off); -} - -/* - * Compute the length for, and possibly generate, an AF_LINK-family interface - * address record. - */ -static ssize_t -gen_ifam_dl(const struct nic * nic, int ndx, int is_up, - struct rmib_oldp * oldp, ssize_t off) -{ - struct ifa_msghdr ifam; - char buf[SDL_BUFSIZE]; - void *rta_map[RTAX_MAX]; - size_t rta_len[RTAX_MAX], size; - - if (oldp != NULL) { - memset(&ifam, 0, sizeof(ifam)); - ifam.ifam_version = RTM_VERSION; - ifam.ifam_type = RTM_NEWADDR; - ifam.ifam_index = ndx; - ifam.ifam_metric = 0; /* unknown and irrelevant */ - } - - size = make_sdl(nic, ndx, (oldp != NULL) ? buf : NULL, sizeof(buf)); - - /* - * We do not generate a netmask. NetBSD seems to generate a netmask - * with all-one bits for the number of bytes equal to the name length, - * for reasons unknown to me. If we did the same, we would end up with - * a conflict on the static 'namebuf' buffer. - */ - memset(rta_map, 0, sizeof(rta_map)); - rta_map[RTAX_IFA] = buf; - rta_len[RTAX_IFA] = size; - - return copyout_rta(&ifam, sizeof(ifam), &ifam.ifam_msglen, - &ifam.ifam_addrs, rta_map, rta_len, oldp, off); -} - -/* - * Compute the length for, and possibly generate, an AF_INET-family interface - * address record. - */ -static ssize_t -gen_ifam_inet(const struct nic * nic, int ndx, int is_up, - struct rmib_oldp * oldp, ssize_t off) -{ - struct ifa_msghdr ifam; - struct sockaddr_in ipaddr, netmask; - void *rta_map[RTAX_MAX]; - size_t rta_len[RTAX_MAX]; - - if (oldp != NULL) { - memset(&ifam, 0, sizeof(ifam)); - ifam.ifam_msglen = sizeof(ifam); - ifam.ifam_version = RTM_VERSION; - ifam.ifam_type = RTM_NEWADDR; - ifam.ifam_addrs = 0; - ifam.ifam_index = ndx; - ifam.ifam_metric = 0; /* unknown and irrelevant */ - } - - memset(rta_map, 0, sizeof(rta_map)); - - if (!ip_addr_isany(&nic->netif.ip_addr)) { - if (oldp != NULL) { - memset(&ipaddr, 0, sizeof(ipaddr)); - ipaddr.sin_family = AF_INET; - ipaddr.sin_len = sizeof(ipaddr); - ipaddr.sin_addr.s_addr = - ip4_addr_get_u32(&nic->netif.ip_addr); - } - - rta_map[RTAX_IFA] = &ipaddr; - rta_len[RTAX_IFA] = sizeof(ipaddr); - } - - if (!ip_addr_isany(&nic->netif.netmask)) { - /* - * TODO: BSD goes through the trouble of compressing the - * netmask for some reason. We need to figure out if - * compression is actually required by any part of userland. - */ - if (oldp != NULL) { - memset(&netmask, 0, sizeof(netmask)); - netmask.sin_family = AF_INET; - netmask.sin_len = sizeof(netmask); - netmask.sin_addr.s_addr = - ip4_addr_get_u32(&nic->netif.netmask); - } - - rta_map[RTAX_NETMASK] = &netmask; - rta_len[RTAX_NETMASK] = sizeof(netmask); - } - - return copyout_rta(&ifam, sizeof(ifam), &ifam.ifam_msglen, - &ifam.ifam_addrs, rta_map, rta_len, oldp, off); -} - -/* - * Compute the size needed for, and optionally copy out, the interface and - * address information for the given interface. - */ -static ssize_t -do_one_if(const struct nic * nic, int ndx, struct rmib_oldp * oldp, - ssize_t off, int filter) -{ - ssize_t r, len; - int is_up; - - /* - * If the interface is not configured, we mark it as down and do not - * provide IP address information. - */ - is_up = !ip_addr_isany(&nic->netif.ip_addr); - - len = 0; - - /* There is always a full interface information record. */ - if ((r = gen_ifm(nic, ndx, is_up, oldp, off)) < 0) - return r; - len += r; - - /* If not filtered, there is a datalink address record. */ - if (filter == 0 || filter == AF_LINK) { - if ((r = gen_ifam_dl(nic, ndx, is_up, oldp, off + len)) < 0) - return r; - len += r; - } - - /* If configured and not filtered, there is an IPv4 address record. */ - if (is_up && (filter == 0 || filter == AF_INET)) { - if ((r = gen_ifam_inet(nic, ndx, is_up, oldp, off + len)) < 0) - return r; - len += r; - } - - /* - * Whether or not anything was copied out, upon success we return the - * full length of the data. - */ - return len; -} - -/* - * Remote MIB implementation of CTL_NET PF_ROUTE 0. This function handles all - * queries on the "net.route.rtable" sysctl(2) node. - */ -static ssize_t -net_route_rtable(struct rmib_call * call, struct rmib_node * node __unused, - struct rmib_oldp * oldp, struct rmib_newp * newp __unused) -{ - const struct nic *nic; - ssize_t r, off; - int i, filter, ndx; - - if (call->call_namelen != 3) - return EINVAL; - - /* We only support listing interfaces for now. */ - if (call->call_name[1] != NET_RT_IFLIST) - return EOPNOTSUPP; - - filter = call->call_name[0]; - ndx = call->call_name[2]; - - off = 0; - - for (i = 0; i < MAX_DEVS; i++) { - if (!(nic = nic_get(i))) - continue; - - /* - * If information about a specific interface index is requested - * then skip all other entries. Interface indices must be - * nonzero, so we shift the numbers by one. We can avoid going - * through the loop altogether here, but getifaddrs(3) does not - * query specific interfaces anyway. - */ - if (ndx != 0 && ndx != i + 1) - continue; - - /* Avoid generating results that are never copied out. */ - if (oldp != NULL && !rmib_inrange(oldp, off)) - oldp = NULL; - - if ((r = do_one_if(nic, i + 1, oldp, off, filter)) < 0) - return r; - - off += r; - } - - return off; -} - -/* The CTL_NET PF_ROUTE subtree. */ -static struct rmib_node net_route_table[] = { - [0] = RMIB_FUNC(RMIB_RO | CTLTYPE_NODE, 0, net_route_rtable, - "rtable", "Routing table information") -}; - -/* The CTL_NET PF_ROUTE node. */ -static struct rmib_node net_route_node = - RMIB_NODE(RMIB_RO, net_route_table, "route", "PF_ROUTE information"); - -/* - * Register the net.route RMIB subtree with the MIB service. Since inet does - * not support clean shutdowns, there is no matching cleanup function. - */ -void -rtinfo_init(void) -{ - const int mib[] = { CTL_NET, PF_ROUTE }; - int r; - - if ((r = rmib_register(mib, __arraycount(mib), &net_route_node)) != OK) - panic("unable to register remote MIB tree: %d", r); -} diff --git a/minix/net/lwip/tcp.c b/minix/net/lwip/tcp.c deleted file mode 100644 index cebd6df4b..000000000 --- a/minix/net/lwip/tcp.c +++ /dev/null @@ -1,1196 +0,0 @@ -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include "proto.h" - -#define TCP_BUF_SIZE (32 << 10) - -#define sock_alloc_buf(s) debug_malloc(s) -#define sock_free_buf(x) debug_free(x) - -static int do_tcp_debug; - -#if 0 -#define debug_tcp_print(str, ...) printf("LWIP %s:%d : " str "\n", \ - __func__, __LINE__, ##__VA_ARGS__) -#else -#define debug_tcp_print(...) debug_print(__VA_ARGS__) -#endif - -struct wbuf { - unsigned int len; - unsigned int written; - unsigned int unacked; - unsigned int rem_len; - struct wbuf * next; - char data[]; -}; - -struct wbuf_chain { - struct wbuf * head; - struct wbuf * tail; - struct wbuf * unsent; /* points to the first buffer that contains unsent - data. It may point anywhere between head and - tail */ -}; - -static void tcp_error_callback(void *arg, err_t err) -{ - int perr; - struct socket * sock = (struct socket *) arg; - - debug_tcp_print("socket num %ld err %d", get_sock_num(sock), err); - - switch (err) { - case ERR_RST: - perr = ECONNREFUSED; - break; - case ERR_CLSD: - perr = EPIPE; - break; - case ERR_CONN: - perr = ENOTCONN; - break; - default: - perr = EIO; - } - - /* FIXME: what if this is for a write that was already replied to? */ - if (sock->flags & SOCK_FLG_OP_PENDING) { - send_req_reply(&sock->req, perr); - sock->flags &= ~SOCK_FLG_OP_PENDING; - } else if (sock_select_set(sock)) - sock_select_notify(sock); - /* - * When error callback is called the tcb either does not exist anymore - * or is going to be deallocated soon after. We must not use the pcb - * anymore - */ - sock->pcb = NULL; -} - -static int tcp_fill_new_socket(struct socket * sock, struct tcp_pcb * pcb) -{ - struct wbuf_chain * wc; - - if (!(wc = malloc(sizeof(struct wbuf_chain)))) - return ENOMEM; - - wc-> head = wc->tail = wc->unsent = NULL; - sock->buf = wc; - sock->buf_size = 0; - - sock->pcb = pcb; - tcp_arg(pcb, sock); - tcp_err(pcb, tcp_error_callback); - tcp_nagle_disable(pcb); - - return OK; -} - -static int tcp_op_open(struct socket * sock) -{ - struct tcp_pcb * pcb; - int ret; - - debug_tcp_print("socket num %ld", get_sock_num(sock)); - - if (!(pcb = tcp_new())) - return ENOMEM; - debug_tcp_print("new tcp pcb %p\n", pcb); - - if ((ret = tcp_fill_new_socket(sock, pcb)) != OK) - tcp_abandon(pcb, 0); - - return ret; -} - -static void tcp_recv_free(__unused void * data) -{ - pbuf_free((struct pbuf *) data); -} - -static void tcp_backlog_free(void * data) -{ - tcp_abort((struct tcp_pcb *) data); -} - -static void free_wbuf_chain(struct wbuf_chain * wc) -{ - struct wbuf * wb; - - assert(wc != NULL); - - wb = wc->head; - while (wb) { - struct wbuf * w = wb; - debug_tcp_print("freeing wbuf %p", wb); - wb = wb->next; - debug_free(w); - } - - debug_free(wc); -} - -static int tcp_op_close(struct socket * sock) -{ - debug_tcp_print("socket num %ld", get_sock_num(sock)); - - if (sock->flags & SOCK_FLG_OP_LISTENING) - sock_dequeue_data_all(sock, tcp_backlog_free); - else - sock_dequeue_data_all(sock, tcp_recv_free); - debug_tcp_print("dequed RX data"); - - if (sock->pcb) { - int err; - - /* we are not able to handle any callback anymore */ - if (((struct tcp_pcb *)sock->pcb)->state != LISTEN) { - tcp_arg((struct tcp_pcb *)sock->pcb, NULL); - tcp_err((struct tcp_pcb *)sock->pcb, NULL); - tcp_sent((struct tcp_pcb *)sock->pcb, NULL); - tcp_recv((struct tcp_pcb *)sock->pcb, NULL); - } - - err = tcp_close(sock->pcb); - if(err != ERR_OK) - panic("tcp_close failed\n"); - sock->pcb = NULL; - } - debug_tcp_print("freed pcb"); - - if (sock->buf) { - free_wbuf_chain((struct wbuf_chain *) sock->buf); - sock->buf = NULL; - } - debug_tcp_print("freed TX data"); - - debug_tcp_print("socket unused"); - - /* mark it as unused */ - sock->ops = NULL; - - return OK; -} - -__unused static void print_tcp_payload(unsigned char * buf, int len) -{ - int i; - - printf("LWIP tcp payload (%d) :\n", len); - for (i = 0; i < len; i++, buf++) { - printf("%02x ", buf[0]); - if (i % 8 == 7) - kputc('\n'); - } - kputc('\n'); -} - -static int read_from_tcp(struct socket * sock, struct sock_req * req) -{ - unsigned int rem_buf, written = 0; - struct pbuf * p; - - assert(!(sock->flags & SOCK_FLG_OP_LISTENING) && sock->recv_head); - - rem_buf = req->size; - - debug_tcp_print("socket num %ld recv buff sz %d", get_sock_num(sock), rem_buf); - - p = (struct pbuf *)sock->recv_head->data; - while (rem_buf) { - int err; - - if (rem_buf >= p->len) { - struct pbuf * np; - - /* - * FIXME perhaps copy this to a local buffer and do a - * single copy to user then - */ -#if 0 - print_tcp_payload(p->payload, p->len); -#endif - err = copy_to_user(req->endpt, p->payload, p->len, - req->grant, written); - if (err != OK) - goto cp_error; - sock->recv_data_size -= p->len; - - debug_tcp_print("whole pbuf copied (%d bytes)", p->len); - rem_buf -= p->len; - written += p->len; - - if ((np = p->next)) { - pbuf_ref(np); - if (pbuf_free(p) != 1) - panic("LWIP : pbuf_free != 1"); - /* - * Mark where we are going to continue if an - * error occurs - */ - sock->recv_head->data = np; - p = np; - } else { - sock_dequeue_data(sock); - pbuf_free(p); - if (sock->recv_head) - p = (struct pbuf *)sock->recv_head->data; - else - break; - } - - if (rem_buf == 0) - break; - } else { - /* - * It must be PBUF_RAM for us to be able to shift the - * payload pointer - */ - assert(p->type == PBUF_RAM); - -#if 0 - print_tcp_payload(p->payload, rem_buf); -#endif - err = copy_to_user(req->endpt, p->payload, rem_buf, - req->grant, written); - if (err != OK) - goto cp_error; - sock->recv_data_size -= rem_buf; - - debug_tcp_print("partial pbuf copied (%d bytes)", rem_buf); - /* - * The whole pbuf hasn't been copied out, we only shift - * the payload pointer to remember where to continue - * next time - */ - pbuf_header(p, -rem_buf); - written += rem_buf; - break; - } - } - - debug_tcp_print("%d bytes written to userspace", written); - //printf("%d wr, queue %d\n", written, sock->recv_data_size); - tcp_recved((struct tcp_pcb *) sock->pcb, written); - return written; - -cp_error: - if (written) { - debug_tcp_print("%d bytes written to userspace", written); - return written; - } else - return EFAULT; -} - -static int tcp_op_read(struct socket * sock, struct sock_req * req, int blk) -{ - debug_tcp_print("socket num %ld", get_sock_num(sock)); - - if (!sock->pcb || ((struct tcp_pcb *) sock->pcb)->state != - ESTABLISHED) { - debug_tcp_print("Connection not established\n"); - return ENOTCONN; - } - if (sock->recv_head) { - /* data available receive immeditely */ - int ret = read_from_tcp(sock, req); - debug_tcp_print("read op finished"); - return ret; - } else { - if (sock->flags & SOCK_FLG_CLOSED) { - printf("socket %ld already closed!!! call from %d\n", - get_sock_num(sock), req->endpt); - do_tcp_debug = 1; - return 0; - } - if (!blk) { - debug_tcp_print("reading would block -> EAGAIN"); - return EAGAIN; - } - /* operation is being processed */ - sock->req = *req; - debug_tcp_print("no data to read, suspending"); - sock->flags |= SOCK_FLG_OP_PENDING | SOCK_FLG_OP_READING; - return EDONTREPLY; - } -} - -static struct wbuf * wbuf_add(struct socket * sock, unsigned int sz) -{ - struct wbuf * wbuf; - struct wbuf_chain * wc = (struct wbuf_chain *)sock->buf; - - assert(wc); - - wbuf = debug_malloc(sizeof(struct wbuf) + sz); - if (!wbuf) - return NULL; - - wbuf->len = sz; - wbuf->written = wbuf->unacked = 0; - wbuf->next = NULL; - - if (wc->head == NULL) - wc->head = wc->tail = wbuf; - else { - wc->tail->next = wbuf; - wc->tail = wbuf; - } - - sock->buf_size += sz; - debug_tcp_print("buffer %p size %d\n", wbuf, sock->buf_size); - - return wbuf; -} - -static struct wbuf * wbuf_ack_sent(struct socket * sock, unsigned int sz) -{ - struct wbuf_chain * wc = (struct wbuf_chain *) sock->buf; - struct wbuf ** wb; - - wb = &wc->head; - while (sz && *wb) { - if ((*wb)->unacked <= sz) { - struct wbuf * w; - assert((*wb)->rem_len == 0); - w = *wb; - *wb = w->next; - sock->buf_size -= w->len; - sz -= w->unacked; - debug_tcp_print("whole buffer acked (%d / %d), removed", - w->unacked, w->len); - debug_free(w); - } else { - (*wb)->unacked -= sz; - (*wb)->written += sz; - debug_tcp_print("acked %d / %d bytes", sz, (*wb)->len); - sz = 0; - } - } - - /* did we write out more than we had? */ - assert(sz == 0); - - if (wc->head == NULL) - wc->tail = NULL; - debug_tcp_print("buffer size %d\n", sock->buf_size); - - return wc->head; -} - -static int tcp_op_write(struct socket * sock, struct sock_req * req, - __unused int blk) -{ - int ret; - struct wbuf * wbuf; - unsigned int snd_buf_len, usr_buf_len; - u8_t flgs = 0; - - - if (!sock->pcb) - return ENOTCONN; - - usr_buf_len = req->size; - debug_tcp_print("socket num %ld data size %d", - get_sock_num(sock), usr_buf_len); - - /* - * Let at most one buffer grow beyond TCP_BUF_SIZE. This is to minimize - * small writes from userspace if only a few bytes were sent before - */ - if (sock->buf_size >= TCP_BUF_SIZE) { - /* FIXME do not block for now */ - debug_tcp_print("WARNING : tcp buffers too large, cannot allocate more"); - return ENOMEM; - } - /* - * Never let the allocated buffers grow more than to 2xTCP_BUF_SIZE and - * never copy more than space available - */ - usr_buf_len = (usr_buf_len > TCP_BUF_SIZE ? TCP_BUF_SIZE : usr_buf_len); - wbuf = wbuf_add(sock, usr_buf_len); - debug_tcp_print("new wbuf for %d bytes", wbuf->len); - - if (!wbuf) { - debug_tcp_print("cannot allocate new buffer of %d bytes", usr_buf_len); - return ENOMEM; - } - - if ((ret = copy_from_user(req->endpt, wbuf->data, usr_buf_len, - req->grant, 0)) != OK) { - return ret; - } - - wbuf->written = 0; - wbuf->rem_len = usr_buf_len; - - /* - * If a writing operation is already in progress, we just enqueue the - * data and quit. - */ - if (sock->flags & SOCK_FLG_OP_WRITING) { - struct wbuf_chain * wc = (struct wbuf_chain *)sock->buf; - /* - * We are adding a buffer with unsent data. If we don't have any other - * unsent data, set the pointer to this buffer. - */ - if (wc->unsent == NULL) { - wc->unsent = wbuf; - debug_tcp_print("unsent %p remains %d\n", wbuf, wbuf->rem_len); - } - debug_tcp_print("returns %d\n", usr_buf_len); - /* - * We cannot accept new operations (write). We set the flag - * after sending reply not to revive only. We could deadlock. - */ - /* - * FIXME: this looks like bad logic. We acknowledge the write - * operation, so we will never reply to it or cancel it later. - */ - if (sock->buf_size >= TCP_BUF_SIZE) - sock->flags |= SOCK_FLG_OP_PENDING; - - return usr_buf_len; - } - - /* - * Start sending data if the operation is not in progress yet. The - * current buffer is the nly one we have, we cannot send more. - */ - - snd_buf_len = tcp_sndbuf((struct tcp_pcb *)sock->pcb); - debug_tcp_print("tcp can accept %d bytes", snd_buf_len); - - wbuf->unacked = (snd_buf_len < wbuf->rem_len ? snd_buf_len : wbuf->rem_len); - wbuf->rem_len -= wbuf->unacked; - - if (wbuf->rem_len) { - flgs = TCP_WRITE_FLAG_MORE; - /* - * Remember that this buffer has some data which we didn't pass - * to tcp yet. - */ - ((struct wbuf_chain *)sock->buf)->unsent = wbuf; - debug_tcp_print("unsent %p remains %d\n", wbuf, wbuf->rem_len); - } - - ret = tcp_write((struct tcp_pcb *)sock->pcb, wbuf->data, - wbuf->unacked, flgs); - tcp_output((struct tcp_pcb *)sock->pcb); - debug_tcp_print("%d bytes to tcp", wbuf->unacked); - - if (ret == ERR_OK) { - /* - * Operation is being processed, no need to remember the message - * in this case, we are going to reply immediatly - */ - debug_tcp_print("returns %d\n", usr_buf_len); - sock->flags |= SOCK_FLG_OP_WRITING; - /* - * FIXME: this looks like bad logic. We acknowledge the write - * operation, so we will never reply to it or cancel it later. - */ - if (sock->buf_size >= TCP_BUF_SIZE) - sock->flags |= SOCK_FLG_OP_PENDING; - return usr_buf_len; - } else - return EIO; -} - -static int tcp_set_conf(struct socket * sock, endpoint_t endpt, - cp_grant_id_t grant) -{ - int err; - nwio_tcpconf_t tconf; - struct tcp_pcb * pcb = (struct tcp_pcb *) sock->pcb; - - debug_tcp_print("socket num %ld", get_sock_num(sock)); - - assert(pcb); - - err = copy_from_user(endpt, &tconf, sizeof(tconf), grant, 0); - - if (err != OK) - return err; - - debug_tcp_print("tconf.nwtc_flags = 0x%x", tconf.nwtc_flags); - debug_tcp_print("tconf.nwtc_remaddr = 0x%x", - (unsigned int) tconf.nwtc_remaddr); - debug_tcp_print("tconf.nwtc_remport = 0x%x", ntohs(tconf.nwtc_remport)); - debug_tcp_print("tconf.nwtc_locaddr = 0x%x", - (unsigned int) tconf.nwtc_locaddr); - debug_tcp_print("tconf.nwtc_locport = 0x%x", ntohs(tconf.nwtc_locport)); - - sock->usr_flags = tconf.nwtc_flags; - - if (sock->usr_flags & NWTC_SET_RA) - pcb->remote_ip.addr = tconf.nwtc_remaddr; - if (sock->usr_flags & NWTC_SET_RP) - pcb->remote_port = ntohs(tconf.nwtc_remport); - - if (sock->usr_flags & NWTC_LP_SET) { - /* FIXME the user library can only bind to ANY anyway */ - if (tcp_bind(pcb, IP_ADDR_ANY, ntohs(tconf.nwtc_locport)) == ERR_USE) { - return EADDRINUSE; - } - } - - return OK; -} - -static int tcp_get_conf(struct socket * sock, endpoint_t endpt, - cp_grant_id_t grant) -{ - nwio_tcpconf_t tconf; - struct tcp_pcb * pcb = (struct tcp_pcb *) sock->pcb; - - debug_tcp_print("socket num %ld", get_sock_num(sock)); - - assert(pcb); - - tconf.nwtc_locaddr = pcb->local_ip.addr; - tconf.nwtc_locport = htons(pcb->local_port); - tconf.nwtc_remaddr = pcb->remote_ip.addr; - tconf.nwtc_remport = htons(pcb->remote_port); - tconf.nwtc_flags = sock->usr_flags; - - debug_tcp_print("tconf.nwtc_flags = 0x%x", tconf.nwtc_flags); - debug_tcp_print("tconf.nwtc_remaddr = 0x%x", - (unsigned int) tconf.nwtc_remaddr); - debug_tcp_print("tconf.nwtc_remport = 0x%x", ntohs(tconf.nwtc_remport)); - debug_tcp_print("tconf.nwtc_locaddr = 0x%x", - (unsigned int) tconf.nwtc_locaddr); - debug_tcp_print("tconf.nwtc_locport = 0x%x", ntohs(tconf.nwtc_locport)); - - return copy_to_user(endpt, &tconf, sizeof(tconf), grant, 0); -} - -static int enqueue_rcv_data(struct socket * sock, struct pbuf * pbuf) -{ - /* Do not enqueue more data than allowed */ - if (0 && sock->recv_data_size > 4 * TCP_BUF_SIZE) - return ERR_MEM; - - if (sock_enqueue_data(sock, pbuf, pbuf->tot_len) != OK) { - debug_tcp_print("data enqueueing failed"); - return ERR_MEM; - } - debug_tcp_print("enqueued %d bytes", pbuf->tot_len); - //printf("enqueued %d bytes, queue %d\n", pbuf->tot_len, sock->recv_data_size); - - return ERR_OK; -} - -static err_t tcp_recv_callback(void *arg, - struct tcp_pcb *tpcb, - struct pbuf *pbuf, - err_t err) -{ - int ret, enqueued = 0; - struct socket * sock = (struct socket *) arg; - - debug_tcp_print("socket num %ld", get_sock_num(sock)); - - if (sock->pcb == NULL) { - if (sock_select_set(sock)) - sock_select_notify(sock); - return ERR_OK; - } - - assert((struct tcp_pcb *) sock->pcb == tpcb); - - if (err != ERR_OK) - return ERR_OK; - if (!pbuf) { - debug_tcp_print("tcp stream closed on the remote side"); - // sock->flags |= SOCK_FLG_CLOSED; - - /* wake up the reader and report EOF */ - if (sock->flags & SOCK_FLG_OP_PENDING && - sock->flags & SOCK_FLG_OP_READING) { - send_req_reply(&sock->req, 0); - sock->flags &= ~(SOCK_FLG_OP_PENDING | - SOCK_FLG_OP_READING); - } -#if 0 - /* if there are any undelivered data, drop them */ - sock_dequeue_data_all(sock, tcp_recv_free); - tcp_abandon(tpcb, 0); - sock->pcb = NULL; -#endif - - return ERR_OK; - } - - /* - * FIXME we always enqueue the data first. If the head is empty and read - * operation is pending we could try to deliver immeditaly without - * enqueueing - */ - if (enqueue_rcv_data(sock, pbuf) == ERR_OK) - enqueued = 1; - - /* - * Deliver data if there is a pending read operation, otherwise notify - * select if the socket is being monitored - */ - if (sock->flags & SOCK_FLG_OP_PENDING) { - if (sock->flags & SOCK_FLG_OP_READING) { - ret = read_from_tcp(sock, &sock->req); - debug_tcp_print("read op finished"); - send_req_reply(&sock->req, ret); - sock->flags &= ~(SOCK_FLG_OP_PENDING | - SOCK_FLG_OP_READING); - } - } else if (!(sock->flags & SOCK_FLG_OP_WRITING) && - sock_select_rw_set(sock)) - sock_select_notify(sock); - - /* perhaps we have deliverd some data to user, try to enqueue again */ - if (!enqueued) { - return enqueue_rcv_data(sock, pbuf); - } else - return ERR_OK; -} - -static err_t tcp_sent_callback(void *arg, struct tcp_pcb *tpcb, u16_t len) -{ - struct socket * sock = (struct socket *) arg; - struct wbuf * wbuf; - struct wbuf_chain * wc = (struct wbuf_chain *) sock->buf; - unsigned int snd_buf_len; - int ret; - - debug_tcp_print("socket num %ld", get_sock_num(sock)); - - /* an error might have had happen */ - if (sock->pcb == NULL) { - if (sock_select_set(sock)) - sock_select_notify(sock); - return ERR_OK; - } - - assert((struct tcp_pcb *)sock->pcb == tpcb); - - /* operation must have been canceled, do not send any other data */ - /* - * FIXME: this looks like bad logic. We already acknowledged the write - * operation, so we should not set or check the OP_PENDING flag.. - */ - if (!(sock->flags & SOCK_FLG_OP_PENDING)) - return ERR_OK; - - wbuf = wbuf_ack_sent(sock, len); - - if (wbuf == NULL) { - debug_tcp_print("all data acked, nothing more to send"); - sock->flags &= ~SOCK_FLG_OP_WRITING; - if (!(sock->flags & SOCK_FLG_OP_READING)) - sock->flags &= ~SOCK_FLG_OP_PENDING; - /* no reviving, we must notify. Write and read possible */ - if (sock_select_rw_set(sock)) - sock_select_notify(sock); - return ERR_OK; - } - - /* we have just freed some space, write will be accepted */ - if (sock->buf_size < TCP_BUF_SIZE && sock_select_rw_set(sock)) { - if (!(sock->flags & SOCK_FLG_OP_READING)) { - sock->flags &= ~SOCK_FLG_OP_PENDING; - sock_select_notify(sock); - } - } - - /* - * Check if there is some space for new data, there should be, we just - * got a confirmation that some data reached the other end of the - * connection - */ - snd_buf_len = tcp_sndbuf(tpcb); - assert(snd_buf_len > 0); - debug_tcp_print("tcp can accept %d bytes", snd_buf_len); - - if (!wc->unsent) { - debug_tcp_print("nothing to send"); - return ERR_OK; - } - - wbuf = wc->unsent; - while (wbuf) { - unsigned int towrite; - u8_t flgs = 0; - - towrite = (snd_buf_len < wbuf->rem_len ? - snd_buf_len : wbuf->rem_len); - wbuf->rem_len -= towrite; - debug_tcp_print("data to send, sending %d", towrite); - - if (wbuf->rem_len || wbuf->next) - flgs = TCP_WRITE_FLAG_MORE; - ret = tcp_write(tpcb, wbuf->data + wbuf->written + wbuf->unacked, - towrite, flgs); - debug_tcp_print("%d bytes to tcp", towrite); - - /* tcp_output() is called once we return from this callback */ - - if (ret != ERR_OK) { - debug_print("tcp_write() failed (%d), written %d" - , ret, wbuf->written); - sock->flags &= ~(SOCK_FLG_OP_PENDING | SOCK_FLG_OP_WRITING); - /* no reviving, we must notify. Write and read possible */ - if (sock_select_rw_set(sock)) - sock_select_notify(sock); - return ERR_OK; - } - - wbuf->unacked += towrite; - snd_buf_len -= towrite; - debug_tcp_print("tcp still accepts %d bytes\n", snd_buf_len); - - if (snd_buf_len) { - assert(wbuf->rem_len == 0); - wbuf = wbuf->next; - wc->unsent = wbuf; - if (wbuf) - debug_tcp_print("unsent %p remains %d\n", - wbuf, wbuf->rem_len); - else { - debug_tcp_print("nothing to send"); - } - } else - break; - } - - return ERR_OK; -} - -static err_t tcp_connected_callback(void *arg, - struct tcp_pcb *tpcb, - __unused err_t err) -{ - struct socket * sock = (struct socket *) arg; - - debug_tcp_print("socket num %ld err %d", get_sock_num(sock), err); - - if (sock->pcb == NULL) { - if (sock_select_set(sock)) - sock_select_notify(sock); - return ERR_OK; - } - - assert((struct tcp_pcb *)sock->pcb == tpcb); - - tcp_sent(tpcb, tcp_sent_callback); - tcp_recv(tpcb, tcp_recv_callback); - send_req_reply(&sock->req, OK); - sock->flags &= ~(SOCK_FLG_OP_PENDING | SOCK_FLG_OP_CONNECTING); - - /* revive does the sock_select_notify() for us */ - - return ERR_OK; -} - -static int tcp_op_connect(struct socket * sock, struct sock_req * req) -{ - ip_addr_t remaddr; - struct tcp_pcb * pcb; - err_t err; - - debug_tcp_print("socket num %ld", get_sock_num(sock)); - /* - * Connecting is going to send some packets. Unless an immediate error - * occurs this operation is going to block - */ - sock->flags |= SOCK_FLG_OP_PENDING | SOCK_FLG_OP_CONNECTING; - - /* try to connect now */ - pcb = (struct tcp_pcb *) sock->pcb; - remaddr = pcb->remote_ip; - sock->req = *req; - err = tcp_connect(pcb, &remaddr, pcb->remote_port, - tcp_connected_callback); - if (err == ERR_VAL) - panic("Wrong tcp_connect arguments"); - if (err != ERR_OK) - panic("Other tcp_connect error %d\n", err); - return EDONTREPLY; -} - -static int tcp_do_accept(struct socket * listen_sock, - struct sock_req * req, - struct tcp_pcb * newpcb) -{ - struct socket * newsock; - unsigned int sock_num; - int ret; - - debug_tcp_print("socket num %ld", get_sock_num(listen_sock)); - - if ((ret = copy_from_user(req->endpt, &sock_num, sizeof(sock_num), - req->grant, 0)) != OK) - return EFAULT; - if (!is_valid_sock_num(sock_num)) - return EBADF; - - newsock = get_sock(sock_num); - assert(newsock->pcb); /* because of previous open() */ - - /* we really want to forget about this socket */ - tcp_err((struct tcp_pcb *)newsock->pcb, NULL); - tcp_abandon((struct tcp_pcb *)newsock->pcb, 0); - - tcp_arg(newpcb, newsock); - tcp_err(newpcb, tcp_error_callback); - tcp_sent(newpcb, tcp_sent_callback); - tcp_recv(newpcb, tcp_recv_callback); - tcp_nagle_disable(newpcb); - tcp_accepted(((struct tcp_pcb *)(listen_sock->pcb))); - newsock->pcb = newpcb; - - debug_tcp_print("Accepted new connection using socket %d\n", sock_num); - - return OK; -} - -static err_t tcp_accept_callback(void *arg, struct tcp_pcb *newpcb, err_t err) -{ - struct socket * sock = (struct socket *) arg; - - debug_tcp_print("socket num %ld", get_sock_num(sock)); - - assert(err == ERR_OK && newpcb); - assert(sock->flags & SOCK_FLG_OP_LISTENING); - - if (sock->flags & SOCK_FLG_OP_PENDING) { - int ret; - - ret = tcp_do_accept(sock, &sock->req, newpcb); - send_req_reply(&sock->req, ret); - sock->flags &= ~SOCK_FLG_OP_PENDING; - if (ret == OK) { - return ERR_OK; - } - /* in case of an error fall through */ - } - - /* If we cannot accept rightaway we enqueue the connection for later */ - - debug_tcp_print("Enqueue connection sock %ld pcb %p\n", - get_sock_num(sock), newpcb); - if (sock_enqueue_data(sock, newpcb, 1) != OK) { - tcp_abort(newpcb); - return ERR_ABRT; - } - if (sock_select_read_set(sock)) - sock_select_notify(sock); - - return ERR_OK; -} - -static int tcp_op_listen(struct socket * sock, endpoint_t endpt, - cp_grant_id_t grant) -{ - int backlog, err; - struct tcp_pcb * new_pcb; - - debug_tcp_print("socket num %ld", get_sock_num(sock)); - - err = copy_from_user(endpt, &backlog, sizeof(backlog), grant, 0); - - if (err != OK) - return err; - - new_pcb = tcp_listen_with_backlog((struct tcp_pcb *) sock->pcb, - (u8_t) backlog); - debug_tcp_print("listening pcb %p", new_pcb); - - if (!new_pcb) { - debug_tcp_print("Cannot listen on socket %ld", get_sock_num(sock)); - return EIO; - } - - /* advertise that this socket is willing to accept connections */ - tcp_accept(new_pcb, tcp_accept_callback); - sock->flags |= SOCK_FLG_OP_LISTENING; - - sock->pcb = new_pcb; - return OK; -} - -static int tcp_op_accept(struct socket * sock, struct sock_req * req) -{ - debug_tcp_print("socket num %ld", get_sock_num(sock)); - - if (!(sock->flags & SOCK_FLG_OP_LISTENING)) { - debug_tcp_print("socket %ld does not listen\n", get_sock_num(sock)); - return EINVAL; - } - - /* there is a connection ready to be accepted */ - if (sock->recv_head) { - int ret; - struct tcp_pcb * pcb; - - pcb = (struct tcp_pcb *) sock->recv_head->data; - assert(pcb); - - ret = tcp_do_accept(sock, req, pcb); - if (ret == OK) - sock_dequeue_data(sock); - return ret; - } - - debug_tcp_print("no ready connection, suspending\n"); - - sock->req = *req; - - sock->flags |= SOCK_FLG_OP_PENDING; - - return EDONTREPLY; -} - -static int tcp_op_shutdown_tx(struct socket * sock) -{ - err_t err; - - debug_tcp_print("socket num %ld", get_sock_num(sock)); - - err = tcp_shutdown((struct tcp_pcb *) sock->pcb, 0, 1); - - switch (err) { - case ERR_OK: - return OK; - case ERR_CONN: - return ENOTCONN; - default: - return EIO; - } -} - -static int tcp_op_get_cookie(struct socket * sock, endpoint_t endpt, - cp_grant_id_t grant) -{ - tcp_cookie_t cookie; - unsigned int sock_num; - - assert(sizeof(cookie) >= sizeof(sock)); - - sock_num = get_sock_num(sock); - memcpy(&cookie, &sock_num, sizeof(sock_num)); - - return copy_to_user(endpt, &cookie, sizeof(sock), grant, 0); -} - -static int tcp_get_opt(struct socket * sock, endpoint_t endpt, - cp_grant_id_t grant) -{ - nwio_tcpopt_t tcpopt; -#if !defined(NDEBUG) - struct tcp_pcb * pcb = (struct tcp_pcb *) sock->pcb; -#endif /* !defined(NDEBUG) */ - - debug_tcp_print("socket num %ld", get_sock_num(sock)); - - assert(pcb); - - /* FIXME : not used by the userspace library */ - tcpopt.nwto_flags = 0; - - return copy_to_user(endpt, &tcpopt, sizeof(tcpopt), grant, 0); -} - -static int tcp_set_opt(struct socket * sock, endpoint_t endpt, - cp_grant_id_t grant) -{ - nwio_tcpopt_t tcpopt; -#if !defined(NDEBUG) - struct tcp_pcb * pcb = (struct tcp_pcb *) sock->pcb; -#endif /* !defined(NDEBUG) */ - - debug_tcp_print("socket num %ld", get_sock_num(sock)); - - assert(pcb); - - /* FIXME : The userspace library does not use this */ - - return copy_from_user(endpt, &tcpopt, sizeof(tcpopt), grant, 0); -} - -static int tcp_op_ioctl(struct socket * sock, struct sock_req * req, - __unused int blk) -{ - int r; - - if (!sock->pcb) - return ENOTCONN; - - debug_tcp_print("socket num %ld req %c %ld %ld", - get_sock_num(sock), - (unsigned char) (req->req >> 8), - req->req & 0xff, _MINIX_IOCTL_SIZE(req->req)); - - switch (req->req) { - case NWIOGTCPCONF: - r = tcp_get_conf(sock, req->endpt, req->grant); - break; - case NWIOSTCPCONF: - r = tcp_set_conf(sock, req->endpt, req->grant); - break; - case NWIOTCPCONN: - r = tcp_op_connect(sock, req); - break; - case NWIOTCPLISTENQ: - r = tcp_op_listen(sock, req->endpt, req->grant); - break; - case NWIOGTCPCOOKIE: - r = tcp_op_get_cookie(sock, req->endpt, req->grant); - break; - case NWIOTCPACCEPTTO: - r = tcp_op_accept(sock, req); - break; - case NWIOTCPSHUTDOWN: - r = tcp_op_shutdown_tx(sock); - break; - case NWIOGTCPOPT: - r = tcp_get_opt(sock, req->endpt, req->grant); - break; - case NWIOSTCPOPT: - r = tcp_set_opt(sock, req->endpt, req->grant); - break; - default: - r = ENOTTY; - } - - return r; -} - -static int tcp_op_select(struct socket * sock, unsigned int sel) -{ - int retsel = 0; - - debug_tcp_print("socket num %ld 0x%x", get_sock_num(sock), sel); - - /* in this case any operation would block, no error */ - if (sock->flags & SOCK_FLG_OP_PENDING) { - debug_tcp_print("SOCK_FLG_OP_PENDING"); - if (sel & CDEV_NOTIFY) { - if (sel & CDEV_OP_RD) { - sock->flags |= SOCK_FLG_SEL_READ; - debug_tcp_print("monitor read"); - } - if (sel & CDEV_OP_WR) { - sock->flags |= SOCK_FLG_SEL_WRITE; - debug_tcp_print("monitor write"); - } - if (sel & CDEV_OP_ERR) - sock->flags |= SOCK_FLG_SEL_ERROR; - } - return 0; - } - - if (sel & CDEV_OP_RD) { - /* - * If recv_head is not NULL we can either read or accept a - * connection which is the same for select() - */ - if (sock->pcb) { - if (sock->recv_head && - !(sock->flags & SOCK_FLG_OP_WRITING)) - retsel |= CDEV_OP_RD; - else if (!(sock->flags & SOCK_FLG_OP_LISTENING) && - ((struct tcp_pcb *) sock->pcb)->state != ESTABLISHED) - retsel |= CDEV_OP_RD; - else if (sel & CDEV_NOTIFY) { - sock->flags |= SOCK_FLG_SEL_READ; - debug_tcp_print("monitor read"); - } - } else /* not connected read does not block */ - retsel |= CDEV_OP_RD; - } - if (sel & CDEV_OP_WR) { - if (sock->pcb) { - if (((struct tcp_pcb *) sock->pcb)->state == ESTABLISHED) - retsel |= CDEV_OP_WR; - else if (sel & CDEV_NOTIFY) { - sock->flags |= SOCK_FLG_SEL_WRITE; - debug_tcp_print("monitor write"); - } - } else /* not connected write does not block */ - retsel |= CDEV_OP_WR; - } - - if (retsel & CDEV_OP_RD) { - debug_tcp_print("read won't block"); - } - if (retsel & CDEV_OP_WR) { - debug_tcp_print("write won't block"); - } - - /* we only monitor if errors will happen in the future */ - if (sel & CDEV_OP_ERR && sel & CDEV_NOTIFY) - sock->flags |= SOCK_FLG_SEL_ERROR; - - return retsel; -} - -static int tcp_op_select_reply(struct socket * sock) -{ - unsigned int sel = 0; - - assert(sock->select_ep != NONE); - debug_tcp_print("socket num %ld", get_sock_num(sock)); - - if (sock->flags & SOCK_FLG_OP_PENDING) { - debug_tcp_print("WARNING socket still blocking!"); - return EDONTREPLY; - } - - if (sock->flags & SOCK_FLG_SEL_READ) { - if (sock->pcb == NULL || (sock->recv_head && - !(sock->flags & SOCK_FLG_OP_WRITING)) || - (!(sock->flags & SOCK_FLG_OP_LISTENING) && - ((struct tcp_pcb *) sock->pcb)->state != - ESTABLISHED)) { - sel |= CDEV_OP_RD; - debug_tcp_print("read won't block"); - } - } - - if (sock->flags & SOCK_FLG_SEL_WRITE && - (sock->pcb == NULL || - ((struct tcp_pcb *) sock->pcb)->state == - ESTABLISHED)) { - sel |= CDEV_OP_WR; - debug_tcp_print("write won't block"); - } - - if (sel) - sock->flags &= ~(SOCK_FLG_SEL_WRITE | SOCK_FLG_SEL_READ | - SOCK_FLG_SEL_ERROR); - - return sel; -} - -struct sock_ops sock_tcp_ops = { - .open = tcp_op_open, - .close = tcp_op_close, - .read = tcp_op_read, - .write = tcp_op_write, - .ioctl = tcp_op_ioctl, - .select = tcp_op_select, - .select_reply = tcp_op_select_reply -}; - diff --git a/minix/net/lwip/udp.c b/minix/net/lwip/udp.c deleted file mode 100644 index 21c4cf7a0..000000000 --- a/minix/net/lwip/udp.c +++ /dev/null @@ -1,404 +0,0 @@ -#include - -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include "proto.h" - -#define UDP_BUF_SIZE (4 << 10) - -#define sock_alloc_buf(s) debug_malloc(s) -#define sock_free_buf(x) debug_free(x) - -#if 0 -#define debug_udp_print(str, ...) printf("LWIP %s:%d : " str "\n", \ - __func__, __LINE__, ##__VA_ARGS__) -#else -#define debug_udp_print(...) debug_print(__VA_ARGS__) -#endif - -struct udp_recv_data { - ip_addr_t ip; - u16_t port; - struct pbuf * pbuf; -}; - -#define udp_recv_alloc() debug_malloc(sizeof(struct udp_recv_data)) - -static void udp_recv_free(void * data) -{ - if (((struct udp_recv_data *)data)->pbuf) - pbuf_free(((struct udp_recv_data *)data)->pbuf); - debug_free(data); -} - -static int udp_op_open(struct socket * sock) -{ - struct udp_pcb * pcb; - - debug_udp_print("socket num %ld", get_sock_num(sock)); - - if (!(pcb = udp_new())) - return ENOMEM; - - sock->buf = NULL; - sock->buf_size = 0; - - sock->pcb = pcb; - - return OK; -} - -static int udp_op_close(struct socket * sock) -{ - debug_udp_print("socket num %ld", get_sock_num(sock)); - - /* deque and free all enqueued data before closing */ - sock_dequeue_data_all(sock, udp_recv_free); - - if (sock->pcb) - udp_remove(sock->pcb); - assert(sock->buf == NULL); - - /* mark it as unused */ - sock->ops = NULL; - - return OK; -} - -static int udp_do_receive(struct socket * sock, - struct sock_req * req, - struct udp_pcb *pcb, - struct pbuf *pbuf, - ip_addr_t *addr, - u16_t port) -{ - struct pbuf * p; - size_t rem_len = req->size; - unsigned int written = 0, hdr_sz = 0; - int err; - - debug_udp_print("user buffer size : %u", rem_len); - - /* FIXME make it both a single copy */ - if (!(sock->usr_flags & NWUO_RWDATONLY)) { - udp_io_hdr_t hdr; - - hdr.uih_src_addr = addr->addr; - hdr.uih_src_port = htons(port); - hdr.uih_dst_addr = pcb->local_ip.addr; - hdr.uih_dst_port = htons(pcb->local_port); - - hdr.uih_data_len = 0; - hdr.uih_ip_opt_len = 0; - - err = copy_to_user(req->endpt, &hdr, sizeof(hdr), req->grant, - 0); - - if (err != OK) - return err; - - rem_len -= (hdr_sz = sizeof(hdr)); - } - - for (p = pbuf; p && rem_len; p = p->next) { - size_t cp_len; - - cp_len = (rem_len < p->len) ? rem_len : p->len; - err = copy_to_user(req->endpt, p->payload, cp_len, req->grant, - hdr_sz + written); - - if (err != OK) - return err; - - written += cp_len; - rem_len -= cp_len; - } - - debug_udp_print("copied %d bytes", written + hdr_sz); - return written + hdr_sz; -} - -static void udp_recv_callback(void *arg, - struct udp_pcb *pcb, - struct pbuf *pbuf, - ip_addr_t *addr, - u16_t port) -{ - struct socket * sock = (struct socket *) arg; - struct udp_recv_data * data; - - debug_udp_print("socket num : %ld addr : %x port : %d\n", - get_sock_num(sock), (unsigned int) addr->addr, port); - - if (sock->flags & SOCK_FLG_OP_PENDING) { - /* we are resuming a suspended operation */ - int ret; - - ret = udp_do_receive(sock, &sock->req, pcb, pbuf, addr, port); - - send_req_reply(&sock->req, ret); - sock->flags &= ~SOCK_FLG_OP_PENDING; - - if (ret > 0) { - pbuf_free(pbuf); - return; - } - } - - /* Do not enqueue more data than allowed */ - if (sock->recv_data_size > UDP_BUF_SIZE) { - pbuf_free(pbuf); - return; - } - - /* - * nobody is waiting for the data or an error occured above, we enqueue - * the packet - */ - if (!(data = udp_recv_alloc())) { - pbuf_free(pbuf); - return; - } - - data->ip = *addr; - data->port = port; - data->pbuf = pbuf; - - if (sock_enqueue_data(sock, data, data->pbuf->tot_len) != OK) { - udp_recv_free(data); - return; - } - - /* - * We don't need to notify when somebody is already waiting, reviving - * read operation will do the trick for us. But we must announce new - * data available here. - */ - if (sock_select_read_set(sock)) - sock_select_notify(sock); -} - -static int udp_op_read(struct socket * sock, struct sock_req * req, int blk) -{ - debug_udp_print("socket num %ld", get_sock_num(sock)); - - if (sock->recv_head) { - /* data available receive immeditely */ - - struct udp_recv_data * data; - int ret; - - data = (struct udp_recv_data *) sock->recv_head->data; - - ret = udp_do_receive(sock, req, (struct udp_pcb *) sock->pcb, - data->pbuf, &data->ip, data->port); - - if (ret > 0) { - sock_dequeue_data(sock); - sock->recv_data_size -= data->pbuf->tot_len; - udp_recv_free(data); - } - return ret; - } else if (!blk) - return EAGAIN; - else { - /* store the message so we know how to reply */ - sock->req = *req; - /* operation is being processes */ - sock->flags |= SOCK_FLG_OP_PENDING; - - debug_udp_print("no data to read, suspending\n"); - return EDONTREPLY; - } -} - -static int udp_op_send(struct socket * sock, - struct pbuf * pbuf, - size_t size) -{ - int err; - - debug_udp_print("pbuf len %d\n", pbuf->len); - - if ((err = udp_send(sock->pcb, pbuf)) == ERR_OK) - return size; - else { - debug_udp_print("udp_send failed %d", err); - return EIO; - } -} - -static int udp_op_sendto(struct socket * sock, struct pbuf * pbuf, size_t size) -{ - int err; - udp_io_hdr_t hdr; - - hdr = *(udp_io_hdr_t *) pbuf->payload; - - pbuf_header(pbuf, -(s16_t)sizeof(udp_io_hdr_t)); - - debug_udp_print("data len %d pbuf len %d\n", - hdr.uih_data_len, pbuf->len); - - if ((err = udp_sendto(sock->pcb, pbuf, (ip_addr_t *) &hdr.uih_dst_addr, - ntohs(hdr.uih_dst_port))) == ERR_OK) - return size; - else { - debug_udp_print("udp_sendto failed %d", err); - return EIO; - } -} - -static int udp_op_write(struct socket * sock, struct sock_req * req, - __unused int blk) -{ - int ret; - struct pbuf * pbuf; - - debug_udp_print("socket num %ld data size %u", - get_sock_num(sock), req->size); - - pbuf = pbuf_alloc(PBUF_TRANSPORT, req->size, PBUF_POOL); - if (!pbuf) - return ENOMEM; - - if ((ret = copy_from_user(req->endpt, pbuf->payload, req->size, - req->grant, 0)) != OK) { - pbuf_free(pbuf); - return ret; - } - - if (sock->usr_flags & NWUO_RWDATONLY) - ret = udp_op_send(sock, pbuf, req->size); - else - ret = udp_op_sendto(sock, pbuf, req->size); - - if (pbuf_free(pbuf) == 0) { - panic("We cannot buffer udp packets yet!"); - } - - return ret; -} - -static int udp_set_opt(struct socket * sock, endpoint_t endpt, - cp_grant_id_t grant) -{ - int err; - nwio_udpopt_t udpopt; - struct udp_pcb * pcb = (struct udp_pcb *) sock->pcb; - ip_addr_t loc_ip = ip_addr_any; - - assert(pcb); - - err = copy_from_user(endpt, &udpopt, sizeof(udpopt), grant, 0); - - if (err != OK) - return err; - - debug_udp_print("udpopt.nwuo_flags = 0x%lx", udpopt.nwuo_flags); - debug_udp_print("udpopt.nwuo_remaddr = 0x%x", - (unsigned int) udpopt.nwuo_remaddr); - debug_udp_print("udpopt.nwuo_remport = 0x%x", - ntohs(udpopt.nwuo_remport)); - debug_udp_print("udpopt.nwuo_locaddr = 0x%x", - (unsigned int) udpopt.nwuo_locaddr); - debug_udp_print("udpopt.nwuo_locport = 0x%x", - ntohs(udpopt.nwuo_locport)); - - sock->usr_flags = udpopt.nwuo_flags; - - /* - * We will only get data from userspace and the remote address - * and port are being set which means that from now on we must - * know where to send data. Thus we should interpret this as - * connect() call - */ - if (sock->usr_flags & NWUO_RWDATONLY && - sock->usr_flags & NWUO_RP_SET && - sock->usr_flags & NWUO_RA_SET) - udp_connect(pcb, (ip_addr_t *) &udpopt.nwuo_remaddr, - ntohs(udpopt.nwuo_remport)); - /* Setting local address means binding */ - if (sock->usr_flags & NWUO_LP_SET) - udp_bind(pcb, &loc_ip, ntohs(udpopt.nwuo_locport)); - /* We can only bind to random local port */ - if (sock->usr_flags & NWUO_LP_SEL) - udp_bind(pcb, &loc_ip, 0); - - /* register a receive hook */ - udp_recv((struct udp_pcb *) sock->pcb, udp_recv_callback, sock); - - return OK; -} - -static int udp_get_opt(struct socket * sock, endpoint_t endpt, - cp_grant_id_t grant) -{ - nwio_udpopt_t udpopt; - struct udp_pcb * pcb = (struct udp_pcb *) sock->pcb; - - assert(pcb); - - udpopt.nwuo_locaddr = pcb->local_ip.addr; - udpopt.nwuo_locport = htons(pcb->local_port); - udpopt.nwuo_remaddr = pcb->remote_ip.addr; - udpopt.nwuo_remport = htons(pcb->remote_port); - udpopt.nwuo_flags = sock->usr_flags; - - debug_udp_print("udpopt.nwuo_flags = 0x%lx", udpopt.nwuo_flags); - debug_udp_print("udpopt.nwuo_remaddr = 0x%x", - (unsigned int) udpopt.nwuo_remaddr); - debug_udp_print("udpopt.nwuo_remport = 0x%x", - ntohs(udpopt.nwuo_remport)); - debug_udp_print("udpopt.nwuo_locaddr = 0x%x", - (unsigned int) udpopt.nwuo_locaddr); - debug_udp_print("udpopt.nwuo_locport = 0x%x", - ntohs(udpopt.nwuo_locport)); - - return copy_to_user(endpt, &udpopt, sizeof(udpopt), grant, 0); -} - -static int udp_op_ioctl(struct socket * sock, struct sock_req * req, - __unused int blk) -{ - int r; - - debug_udp_print("socket num %ld req %c %ld %ld", - get_sock_num(sock), - (unsigned char) (req->req >> 8), - req->req & 0xff, _MINIX_IOCTL_SIZE(req->req)); - - switch (req->req) { - case NWIOSUDPOPT: - r = udp_set_opt(sock, req->endpt, req->grant); - break; - case NWIOGUDPOPT: - r = udp_get_opt(sock, req->endpt, req->grant); - break; - default: - r = ENOTTY; - } - - return r; -} - -struct sock_ops sock_udp_ops = { - .open = udp_op_open, - .close = udp_op_close, - .read = udp_op_read, - .write = udp_op_write, - .ioctl = udp_op_ioctl, - .select = generic_op_select, - .select_reply = generic_op_select_reply -}; - diff --git a/share/mk/bsd.own.mk b/share/mk/bsd.own.mk index daecca8cc..2c685f9d4 100644 --- a/share/mk/bsd.own.mk +++ b/share/mk/bsd.own.mk @@ -1259,7 +1259,7 @@ _MKVARS.yes= \ #MINIX-specific vars _MKVARS.yes+= \ - MKSYSDEBUG MKLIVEUPDATE MKLWIP MKLLVMCMDS + MKSYSDEBUG MKLIVEUPDATE MKLLVMCMDS .if (${MACHINE_ARCH} == "i386") _MKVARS.yes+= \ MKWATCHDOG MKACPI MKAPIC MKDEBUGREG MKINSTALLBOOT MKPCI diff --git a/share/mk/bsd.prog.mk b/share/mk/bsd.prog.mk index 87bdf50e7..ce10cf5d9 100644 --- a/share/mk/bsd.prog.mk +++ b/share/mk/bsd.prog.mk @@ -235,7 +235,6 @@ LIB${_lib:tu}= ${DESTDIR}/usr/lib/lib${_lib:S/xx/++/:S/atf_c/atf-c/}.a minixfs \ mthread \ netdriver \ - netsock \ sffs \ sockdriver \ sockevent \