1 /* $NetBSD: kmem.c,v 1.3 2018/02/04 08:19:42 mrg Exp $ */ 2 3 /* 4 * Copyright (C) 2012 by Darren Reed. 5 * 6 * See the IPFILTER.LICENCE file for details on licencing. 7 */ 8 /* 9 * kmemcpy() - copies n bytes from kernel memory into user buffer. 10 * returns 0 on success, -1 on error. 11 */ 12 13 #include <stdio.h> 14 #include <sys/param.h> 15 #include <sys/types.h> 16 #include <sys/uio.h> 17 #include <unistd.h> 18 #include <string.h> 19 #include <fcntl.h> 20 #include <sys/file.h> 21 #if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && !defined(linux) && !defined(_AIX51) 22 #include <kvm.h> 23 #endif 24 #include <fcntl.h> 25 #include <sys/socket.h> 26 #include <sys/ioctl.h> 27 #include <netinet/in.h> 28 #include <arpa/inet.h> 29 #include <netinet/in_systm.h> 30 #include <netinet/ip.h> 31 #include <net/if.h> 32 #if __FreeBSD_version >= 300000 33 # include <net/if_var.h> 34 #endif 35 #if defined(linux) || defined(__osf__) || defined(__sgi) || defined(__hpux) 36 # include <stdlib.h> 37 #endif 38 39 #include "kmem.h" 40 41 #ifndef __STDC__ 42 # define const 43 #endif 44 45 #if !defined(lint) 46 static __attribute__((__used__)) const char sccsid[] = "@(#)kmem.c 1.4 1/12/96 (C) 1992 Darren Reed"; 47 static __attribute__((__used__)) const char rcsid[] = "@(#)Id: kmem.c,v 1.1.1.2 2012/07/22 13:44:39 darrenr Exp $"; 48 #endif 49 50 51 52 #if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && \ 53 !defined(linux) && !defined(_AIX51) 54 /* 55 * For all platforms where there is a libkvm and a kvm_t, we use that... 56 */ 57 static kvm_t *kvm_f = NULL; 58 59 #else 60 /* 61 *...and for the others (HP-UX, IRIX, Tru64), we have to provide our own. 62 */ 63 64 typedef int * kvm_t; 65 66 static kvm_t kvm_f = NULL; 67 static char *kvm_errstr = NULL; 68 69 kvm_t kvm_open __P((char *, char *, char *, int, char *)); 70 int kvm_read __P((kvm_t, u_long, char *, size_t)); 71 72 kvm_t kvm_open(kernel, core, swap, mode, errstr) 73 char *kernel, *core, *swap; 74 int mode; 75 char *errstr; 76 { 77 kvm_t k; 78 int fd; 79 80 kvm_errstr = errstr; 81 82 if (core == NULL) 83 core = "/dev/kmem"; 84 85 fd = open(core, mode); 86 if (fd == -1) 87 return NULL; 88 k = malloc(sizeof(*k)); 89 if (k == NULL) 90 return NULL; 91 *k = fd; 92 return k; 93 } 94 95 int kvm_read(kvm, pos, buffer, size) 96 kvm_t kvm; 97 u_long pos; 98 char *buffer; 99 size_t size; 100 { 101 int r = 0, left; 102 char *bufp; 103 104 if (lseek(*kvm, pos, 0) == -1) { 105 if (kvm_errstr != NULL) { 106 fprintf(stderr, "%s", kvm_errstr); 107 perror("lseek"); 108 } 109 return -1; 110 } 111 112 for (bufp = buffer, left = size; left > 0; bufp += r, left -= r) { 113 r = read(*kvm, bufp, left); 114 #ifdef __osf__ 115 /* 116 * Tru64 returns "0" for successful operation, not the number 117 * of bytes read. 118 */ 119 if (r == 0) 120 r = left; 121 #endif 122 if (r <= 0) 123 return -1; 124 } 125 return r; 126 } 127 #endif /* !defined(__sgi) && !defined(__hpux) && !defined(__osf__) */ 128 129 int openkmem(kern, core) 130 char *kern, *core; 131 { 132 kvm_f = kvm_open(kern, core, NULL, O_RDONLY, NULL); 133 if (kvm_f == NULL) 134 { 135 perror("openkmem:open"); 136 return -1; 137 } 138 return kvm_f != NULL; 139 } 140 141 int kmemcpy(buf, pos, n) 142 register char *buf; 143 long pos; 144 register int n; 145 { 146 register int r; 147 148 if (!n) 149 return 0; 150 151 if (kvm_f == NULL) 152 if (openkmem(NULL, NULL) == -1) 153 return -1; 154 155 while ((r = kvm_read(kvm_f, pos, buf, n)) < n) 156 if (r <= 0) 157 { 158 fprintf(stderr, "pos=0x%lx ", (u_long)pos); 159 perror("kmemcpy:read"); 160 return -1; 161 } 162 else 163 { 164 buf += r; 165 pos += r; 166 n -= r; 167 } 168 return 0; 169 } 170 171 int kstrncpy(buf, pos, n) 172 register char *buf; 173 long pos; 174 register int n; 175 { 176 register int r; 177 178 if (!n) 179 return 0; 180 181 if (kvm_f == NULL) 182 if (openkmem(NULL, NULL) == -1) 183 return -1; 184 185 while (n > 0) 186 { 187 r = kvm_read(kvm_f, pos, buf, 1); 188 if (r <= 0) 189 { 190 fprintf(stderr, "pos=0x%lx ", (u_long)pos); 191 perror("kmemcpy:read"); 192 return -1; 193 } 194 else 195 { 196 if (*buf == '\0') 197 break; 198 buf++; 199 pos++; 200 n--; 201 } 202 } 203 return 0; 204 } 205