diff options
Diffstat (limited to 'netcon')
-rw-r--r-- | netcon/NetconEthernetTap.cpp | 56 | ||||
-rwxr-xr-x | netcon/intercept.c | 82 | ||||
-rwxr-xr-x | netcon/libintercept.so.1.0 | bin | 53400 -> 53656 bytes |
3 files changed, 97 insertions, 41 deletions
diff --git a/netcon/NetconEthernetTap.cpp b/netcon/NetconEthernetTap.cpp index 5ef52b72..0921f460 100644 --- a/netcon/NetconEthernetTap.cpp +++ b/netcon/NetconEthernetTap.cpp @@ -503,7 +503,7 @@ int NetconEthernetTap::send_return_value(int fd, int retval, int _errno = 0) [I] EBADF - The descriptor is invalid. [I] ECONNABORTED - A connection has been aborted. [i] EFAULT - The addr argument is not in a writable part of the user address space. - [ ] EINTR - The system call was interrupted by a signal that was caught before a valid connection arrived; see signal(7). + [-] EINTR - The system call was interrupted by a signal that was caught before a valid connection arrived; see signal(7). [ ] EINVAL - Socket is not listening for connections, or addrlen is invalid (e.g., is negative). [I] EINVAL - (accept4()) invalid value in flags. [I] EMFILE - The per-process limit of open file descriptors has been reached. @@ -806,6 +806,12 @@ void NetconEthernetTap::handle_retval(PhySocket *sock, void **uptr, unsigned cha * @param structure containing the data and parameters for this client's RPC * + i := should be implemented in intercept lib + I := is implemented in intercept lib + X := is implemented in service + ? := required treatment Unknown + - := Not needed + [ ] EACCES - The address is protected, and the user is not the superuser. [X] EADDRINUSE - The given address is already in use. [I] EBADF - sockfd is not a valid descriptor. @@ -876,10 +882,16 @@ void NetconEthernetTap::handle_bind(PhySocket *sock, void **uptr, struct bind_st * @param structure containing the data and parameters for this client's RPC * - [?] EADDRINUSE - Another socket is already listening on the same port. - [X] EBADF - The argument sockfd is not a valid descriptor. - [i] ENOTSOCK - The argument sockfd is not a socket. - [i] EOPNOTSUPP - The socket is not of a type that supports the listen() operation. + i := should be implemented in intercept lib + I := is implemented in intercept lib + X := is implemented in service + ? := required treatment Unknown + - := Not needed + +[?] EADDRINUSE - Another socket is already listening on the same port. +[I] EBADF - The argument sockfd is not a valid descriptor. +[I] ENOTSOCK - The argument sockfd is not a socket. +[I] EOPNOTSUPP - The socket is not of a type that supports the listen() operation. */ void NetconEthernetTap::handle_listen(PhySocket *sock, void **uptr, struct listen_st *listen_rpc) @@ -890,6 +902,10 @@ void NetconEthernetTap::handle_listen(PhySocket *sock, void **uptr, struct liste fprintf(stderr, "handle_listen(): PCB is already in listening state.\n"); return; } + + // TODO: Implement liste_with_backlog + // FIXME: Correct return values from this method, most is handled in intercept lib + struct tcp_pcb* listening_pcb = lwipstack->tcp_listen(conn->pcb); if(listening_pcb != NULL) { conn->pcb = listening_pcb; @@ -924,13 +940,17 @@ void NetconEthernetTap::handle_listen(PhySocket *sock, void **uptr, struct liste * @param structure containing the data and parameters for this client's RPC * - TODO: set errno appropriately + i := should be implemented in intercept lib + I := is implemented in intercept lib + X := is implemented in service + ? := required treatment Unknown + - := Not needed [-] EACCES - Permission to create a socket of the specified type and/or protocol is denied. - [?] EAFNOSUPPORT - The implementation does not support the specified address family. - [?] EINVAL - Unknown protocol, or protocol family not available. - [?] EINVAL - Invalid flags in type. - [i] EMFILE - Process file table overflow. + [I] EAFNOSUPPORT - The implementation does not support the specified address family. + [I] EINVAL - Unknown protocol, or protocol family not available. + [I] EINVAL - Invalid flags in type. + [I] EMFILE - Process file table overflow. [i] ENFILE - The system limit on the total number of open files has been reached. [X] ENOBUFS or ENOMEM - Insufficient memory is available. The socket cannot be created until sufficient resources are freed. [?] EPROTONOSUPPORT - The protocol type or the specified protocol is not supported within this domain. @@ -974,23 +994,29 @@ void NetconEthernetTap::handle_socket(PhySocket *sock, void **uptr, struct socke * @param PhySocket associated with this RPC connection * @param structure containing the data and parameters for this client's RPC - --- Error handling in this method will only catch problems which are immeidately + --- Error handling in this method will only catch problems which are immedately apprent. Some errors will need to be caught in the nc_connected(0 callback - [i] EACCES - For UNIX domain sockets, which are identified by pathname: Write permission is denied ... + i := should be implemented in intercept lib + I := is implemented in intercept lib + X := is implemented in service + ? := required treatment Unknown + - := Not needed + + [-] EACCES - For UNIX domain sockets, which are identified by pathname: Write permission is denied ... [ ] EACCES, EPERM - The user tried to connect to a broadcast address without having the socket broadcast flag enabled ... [i] EADDRINUSE - Local address is already in use. [?] EAFNOSUPPORT - The passed address didn't have the correct address family in its sa_family field. [ ] EAGAIN - No more free local ports or insufficient entries in the routing cache. [ ] EALREADY - The socket is nonblocking and a previous connection attempt has not yet been completed. - [ ] EBADF - The file descriptor is not a valid index in the descriptor table. + [I] EBADF - The file descriptor is not a valid index in the descriptor table. [ ] ECONNREFUSED - No-one listening on the remote address. [i] EFAULT - The socket structure address is outside the user's address space. [ ] EINPROGRESS - The socket is nonblocking and the connection cannot be completed immediately. - [?] EINTR - The system call was interrupted by a signal that was caught. + [-] EINTR - The system call was interrupted by a signal that was caught. [X] EISCONN - The socket is already connected. [?] ENETUNREACH - Network is unreachable. - [ ] ENOTSOCK - The file descriptor is not associated with a socket. + [I] ENOTSOCK - The file descriptor is not associated with a socket. [X] ETIMEDOUT - Timeout while attempting connection. * diff --git a/netcon/intercept.c b/netcon/intercept.c index 5060aa2c..4762b309 100755 --- a/netcon/intercept.c +++ b/netcon/intercept.c @@ -528,6 +528,16 @@ int socket(SOCKET_SIG) return -EAFNOSUPPORT; if (socket_type < 0 || socket_type >= SOCK_MAX) return -EINVAL; + /* Check that we haven't hit the soft-limit file descriptors allowed */ + /* FIXME: Find number of open fds + struct rlimit rl; + getrlimit(RLIMIT_NOFILE, &rl); + if(sockfd >= rl.rlim_cur){ + errno = EMFILE; + return -1; + } + */ + /* FIXME: detect ENFILE condition */ #endif #ifdef DUMMY @@ -597,8 +607,21 @@ int socket(SOCKET_SIG) connect() intercept function */ int connect(CONNECT_SIG) { - int err; +#ifdef CHECKS + /* Check that this is a valid fd */ + if(fcntl(__fd, F_GETFD) < 0) { + return -1; + errno = EBADF; + } + /* Check that it is a socket */ + int sock_type; + socklen_t sock_type_len = sizeof(sock_type); + if(getsockopt(__fd, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &sock_type_len) < 0) { + errno = ENOTSOCK; + return -1; + } /* FIXME: Check that address is in user space, return EFAULT ? */ +#endif #ifdef DUMMY dwr("connect(%d)\n", __fd); @@ -606,16 +629,17 @@ int connect(CONNECT_SIG) #else /* make sure we don't touch any standard outputs */ - if(__fd == STDIN_FILENO || __fd == STDOUT_FILENO || __fd == STDERR_FILENO) + if(__fd == STDIN_FILENO || __fd == STDOUT_FILENO || __fd == STDERR_FILENO){ + if (realconnect == NULL) { + dwr("Unresolved symbol: connect(). Library is exiting.\n"); + exit(-1); + } return(realconnect(__fd, __addr, __len)); - int sock_type = -1; - socklen_t sock_type_len = sizeof(sock_type); + } + struct sockaddr_in *connaddr; connaddr = (struct sockaddr_in *) __addr; - getsockopt(__fd, SOL_SOCKET, SO_TYPE, - (void *) &sock_type, &sock_type_len); - if(__addr != NULL && (connaddr->sin_family == AF_LOCAL || connaddr->sin_family == PF_NETLINK || connaddr->sin_family == AF_NETLINK @@ -624,13 +648,9 @@ int connect(CONNECT_SIG) return err; } - char cmd[BUF_SZ]; - if (realconnect == NULL) { - dwr("Unresolved symbol: connect()\n"); - return -1; - } - /* assemble and route command */ + int err; + char cmd[BUF_SZ]; memset(cmd, '\0', BUF_SZ); struct connect_st rpc_st; rpc_st.__tid = syscall(SYS_gettid); @@ -778,7 +798,6 @@ int accept(ACCEPT_SIG) #ifdef CHECKS /* Check that this is a valid fd */ if(fcntl(sockfd, F_GETFD) < 0) { - dwr("EBADF\n"); return -1; errno = EBADF; } @@ -787,13 +806,11 @@ int accept(ACCEPT_SIG) socklen_t sock_type_len = sizeof(sock_type); if(getsockopt(sockfd, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &sock_type_len) < 0) { errno = ENOTSOCK; - dwr("ENOTSOCK\n"); return -1; } /* Check that this socket supports accept() */ if(!(sock_type && (SOCK_STREAM | SOCK_SEQPACKET))) { errno = EOPNOTSUPP; - dwr("EOPNOTSUPP\n"); return -1; } /* Check that we haven't hit the soft-limit file descriptors allowed */ @@ -801,7 +818,6 @@ int accept(ACCEPT_SIG) getrlimit(RLIMIT_NOFILE, &rl); if(sockfd >= rl.rlim_cur){ errno = EMFILE; - dwr("EMFILE\n"); return -1; } #endif @@ -822,16 +838,12 @@ int accept(ACCEPT_SIG) return -1; } - char gmybuf[16]; - int new_conn_socket; - - char c[1]; - int n = read(sockfd, c, sizeof(c)); + char gmybuf[16], c[1]; + int new_conn_socket, n = read(sockfd, c, sizeof(c)); if(n > 0) { ssize_t size = sock_fd_read(fdret_sock, gmybuf, sizeof(gmybuf), &new_conn_socket); - if(size > 0) - { + if(size > 0) { /* Send our local-fd number back to service so it can complete its mapping table */ memset(cmd, '\0', BUF_SZ); cmd[0] = RPC_FD_MAP_COMPLETION; @@ -869,9 +881,27 @@ int accept(ACCEPT_SIG) listen() intercept function */ int listen(LISTEN_SIG) { + #ifdef CHECKS + /* Check that this is a valid fd */ + if(fcntl(sockfd, F_GETFD) < 0) { + return -1; + errno = EBADF; + } + /* Check that it is a socket */ + int sock_type; + socklen_t sock_type_len = sizeof(sock_type); + if(getsockopt(sockfd, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &sock_type_len) < 0) { + errno = ENOTSOCK; + return -1; + } + /* Check that this socket supports accept() */ + if(!(sock_type && (SOCK_STREAM | SOCK_SEQPACKET))) { + errno = EOPNOTSUPP; + return -1; + } + #endif + int err; - /* FIXME: Check that this socket supports listen(), return EOPNOTSUPP */ - /* FIXME: Check that the provided fd is a socket, return ENOTSOCK */ #ifdef DUMMY dwr("listen(%d)\n", sockfd); diff --git a/netcon/libintercept.so.1.0 b/netcon/libintercept.so.1.0 Binary files differindex 1dc1f0da..106c8c20 100755 --- a/netcon/libintercept.so.1.0 +++ b/netcon/libintercept.so.1.0 |