DEFINE_SYSCALL(socketcall, int, call, uintptr_t *, args) { if (call < 1 || call > SYS_SENDMMSG) return -L_EINVAL; if (!mm_check_read(args, nargs[call])) return -L_EFAULT; switch (call) { case SYS_SOCKET: return sys_socket(args[0], args[1], args[2]); case SYS_BIND: return sys_bind(args[0], (const struct sockaddr *)args[1], args[2]); case SYS_CONNECT: return sys_connect(args[0], (const struct sockaddr *)args[1], args[2]); case SYS_LISTEN: return sys_listen(args[0], args[1]); case SYS_ACCEPT: return sys_accept(args[0], (struct sockaddr *)args[1], (int *)args[2]); case SYS_GETSOCKNAME: return sys_getsockname(args[0], (struct sockaddr *)args[1], (int *)args[2]); case SYS_GETPEERNAME: return sys_getpeername(args[0], (struct sockaddr *)args[1], (int *)args[2]); case SYS_SEND: return sys_send(args[0], (const void *)args[1], args[2], args[3]); case SYS_RECV: return sys_recv(args[0], (void *)args[1], args[2], args[3]); case SYS_SENDTO: return sys_sendto(args[0], (const void *)args[1], args[2], args[3], (const struct sockaddr *)args[4], args[5]); case SYS_RECVFROM: return sys_recvfrom(args[0], (void *)args[1], args[2], args[3], (struct sockaddr *)args[4], (int *)args[5]); case SYS_SHUTDOWN: return sys_shutdown(args[0], args[1]); case SYS_SETSOCKOPT: return sys_setsockopt(args[0], args[1], args[2], (const void *)args[3], args[4]); case SYS_GETSOCKOPT: return sys_getsockopt(args[0], args[1], args[2], (void *)args[3], (int *)args[4]); case SYS_SENDMSG: return sys_sendmsg(args[0], (const struct msghdr *)args[1], args[2]); case SYS_RECVMSG: return sys_recvmsg(args[0], (struct msghdr *)args[1], args[2]); case SYS_ACCEPT4: return sys_accept4(args[0], (struct sockaddr *)args[1], (int *)args[2], args[3]); case SYS_SENDMMSG: return sys_sendmmsg(args[0], (struct mmsghdr *)args[1], args[2], args[3]); default: { log_error("Unimplemented socketcall: %d", call); return -L_EINVAL; } } }
int main() { #if defined(SYS_sendmmsg) int s, fd_null; struct sockaddr_in sin1, from; pid_t pid = 0; char buf[2][1024]; fd_set rdfds; struct mmsghdr msgs[2]; struct iovec iov[2]; socklen_t fromlen; /* initialize sockaddr's */ sin1.sin_family = AF_INET; sin1.sin_port = htons((getpid() % 32768) + 11000); sin1.sin_addr.s_addr = INADDR_ANY; pid = start_server(&sin1); fromlen = sizeof(from); memset(msgs, 0, sizeof(msgs)); iov[0].iov_base = buf[0]; iov[0].iov_len = sizeof(buf[0]); msgs[0].msg_hdr.msg_iov = &iov[0]; msgs[0].msg_hdr.msg_iovlen = 1; iov[1].iov_base = buf[1]; iov[1].iov_len = sizeof(buf[1]); msgs[1].msg_hdr.msg_iov = &iov[1]; msgs[1].msg_hdr.msg_iovlen = 1; fd_null = open("/dev/null", O_WRONLY); sys_sendmmsg(-1, msgs, 2, 0); //staptest// sendmmsg (-1, XXXX, 2, 0x0) = -NNNN (EBADF) sys_sendmmsg(fd_null, msgs, 2, MSG_DONTWAIT); //staptest// sendmmsg (NNNN, XXXX, 2, MSG_DONTWAIT) = -NNNN (ENOTSOCK) s = socket(PF_INET, SOCK_DGRAM, 0); //staptest// socket (PF_INET, SOCK_DGRAM, IPPROTO_IP) = NNNN sys_sendmmsg(s, msgs, 2, 0); //staptest// sendmmsg (NNNN, XXXX, 2, 0x0) = -NNNN (EDESTADDRREQ) sys_sendmmsg(s, (struct mmsghdr *)-1, 2, 0); //staptest// sendmmsg (NNNN, 0x[f]+, 2, 0x0) = -NNNN (EFAULT) close(s); //staptest// close (NNNN) = 0 s = socket(PF_INET, SOCK_STREAM, 0); //staptest// socket (PF_INET, SOCK_STREAM, IPPROTO_IP) = NNNN connect(s, (struct sockaddr *)&sin1, sizeof(sin1)); //staptest// connect (NNNN, {AF_INET, 0.0.0.0, NNNN}, 16) = 0 // Note that the exact failure return value can differ here, so // we'll just ignore it. Also note that on a 32-bit kernel (i686 // for instance), MAXSTRINGLEN is only 256. Passing a -1 as the // flags value can produce a string that will cause argstr to get // too big. So, we'll make the end of the argument optional. sys_sendmmsg(s, msgs, 2, -1); //staptest// sendmmsg (NNNN, XXXX, 2, MSG_[^ ]+[[[[|XXXX]]]]?) = NNNN close(s); //staptest// close (NNNN) = 0 s = socket(PF_INET, SOCK_STREAM, 0); //staptest// socket (PF_INET, SOCK_STREAM, IPPROTO_IP) = NNNN connect(s, (struct sockaddr *)&sin1, sizeof(sin1)); //staptest// connect (NNNN, {AF_INET, 0.0.0.0, NNNN}, 16) = 0 // We don't want to wait for -1 vectors, since we'd be waiting for // a long time... sys_sendmmsg(s, msgs, -1, MSG_DONTWAIT); //staptest// sendmmsg (NNNN, XXXX, 4294967295, MSG_DONTWAIT) close(s); //staptest// close (NNNN) = 0 s = socket(PF_INET, SOCK_STREAM, 0); //staptest// socket (PF_INET, SOCK_STREAM, IPPROTO_IP) = NNNN connect(s, (struct sockaddr *)&sin1, sizeof(sin1)); //staptest// connect (NNNN, {AF_INET, 0.0.0.0, NNNN}, 16) = 0 sys_sendmmsg(s, msgs, 2, MSG_DONTWAIT); //staptest// sendmmsg (NNNN, XXXX, 2, MSG_DONTWAIT) = NNNN close(s); //staptest// close (NNNN) = 0 close(fd_null); //staptest// close (NNNN) = 0 if (pid > 0) (void)kill(pid, SIGKILL); /* kill server */ //staptest// kill (NNNN, SIGKILL) = 0 #endif return 0; }