1 /* $OpenBSD: mmap-sysctl-copyout.c,v 1.2 2017/01/13 01:33:14 bluhm Exp $ */ 2 3 #include <sys/param.h> 4 #include <sys/mman.h> 5 #include <sys/queue.h> 6 #include <sys/socket.h> 7 #include <sys/sysctl.h> 8 9 #include <netinet/in.h> 10 #include <netinet/tcp.h> 11 #include <netinet/tcp_seq.h> 12 #include <netinet/tcp_timer.h> 13 #include <netinet/tcp_var.h> 14 15 #include <err.h> 16 #include <fcntl.h> 17 #include <stdlib.h> 18 #include <stdio.h> 19 #include <string.h> 20 #include <unistd.h> 21 22 #define FILE "sysctl-net.inet.tcp.stats" 23 #define CLIENT "/mnt/regress-nfs-client" 24 #define SERVER "/mnt/regress-nfs-server" 25 26 int 27 main(void) 28 { 29 char *p, path[PATH_MAX]; 30 int mib[] = { CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_STATS }; 31 u_int miblen = sizeof(mib) / sizeof(mib[0]); 32 struct tcpstat stats; 33 int fd; 34 size_t len; 35 ssize_t n; 36 37 /* 38 * Initialize file on NFS server. 39 */ 40 snprintf(path, sizeof(path), "%s/%s", SERVER, FILE); 41 if ((fd = open(path, O_RDWR|O_CREAT|O_TRUNC, 0777)) == -1) 42 err(1, "open write '%s'", path); 43 len = sizeof(struct tcpstat); 44 memset(&stats, 0, len); 45 if ((n = write(fd, &stats, len)) == -1) 46 err(1, "write"); 47 if ((size_t)n != len) 48 errx(1, "write not %zu: %zd", len, n); 49 if (close(fd) == -1) 50 err(1, "close read"); 51 52 /* 53 * Map file on NFS client and write sysctl net.inet.tcp.stats into it. 54 */ 55 snprintf(path, sizeof(path), "%s/%s", CLIENT, FILE); 56 if ((fd = open(path, O_RDWR)) == -1) 57 err(1, "open mmap '%s'", path); 58 p = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 59 if (p == MAP_FAILED) 60 err(1, "mmap"); 61 if (sysctl(mib, miblen, p, &len, NULL, 0) == -1) 62 err(1, "sysctl get stat"); 63 if (len != sizeof(struct tcpstat)) 64 errx(1, "len not %zu: %zu", sizeof(struct tcpstat), len); 65 if (close(fd) == -1) 66 err(1, "close mmap"); 67 68 /* 69 * Read file from NFS server. 70 */ 71 snprintf(path, sizeof(path), "%s/%s", SERVER, FILE); 72 if ((fd = open(path, O_RDONLY)) == -1) 73 err(1, "open read '%s'", path); 74 if ((n = read(fd, &stats, len)) == -1) 75 err(1, "read"); 76 if ((size_t)n != len) 77 errx(1, "read not %zu: %zd", len, n); 78 if (close(fd) == -1) 79 err(1, "close read"); 80 81 return (0); 82 } 83