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