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