kmem.c revision 145510
1/* $NetBSD$ */ 2 3/* 4 * Copyright (C) 1993-2001 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) 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) 46static const char sccsid[] = "@(#)kmem.c 1.4 1/12/96 (C) 1992 Darren Reed"; 47static const char rcsid[] = "@(#)Id: kmem.c,v 1.16.2.1 2004/06/20 10:25:58 darrenr Exp"; 48#endif 49 50 51 52#if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && !defined(linux) 53/* 54 * For all platforms where there is a libkvm and a kvm_t, we use that... 55 */ 56static kvm_t *kvm_f = NULL; 57 58#else 59/* 60 *...and for the others (HP-UX, IRIX, Tru64), we have to provide our own. 61 */ 62 63typedef int * kvm_t; 64 65static kvm_t kvm_f = NULL; 66static char *kvm_errstr = NULL; 67 68kvm_t kvm_open __P((char *, char *, char *, int, char *)); 69int kvm_read __P((kvm_t, u_long, char *, size_t)); 70 71kvm_t kvm_open(kernel, core, swap, mode, errstr) 72char *kernel, *core, *swap; 73int mode; 74char *errstr; 75{ 76 kvm_t k; 77 int fd; 78 79 kvm_errstr = errstr; 80 81 if (core == NULL) 82 core = "/dev/kmem"; 83 84 fd = open(core, mode); 85 if (fd == -1) 86 return NULL; 87 k = malloc(sizeof(*k)); 88 if (k == NULL) 89 return NULL; 90 *k = fd; 91 return k; 92} 93 94int kvm_read(kvm, pos, buffer, size) 95kvm_t kvm; 96u_long pos; 97char *buffer; 98size_t size; 99{ 100 int r = 0, left; 101 char *bufp; 102 103 if (lseek(*kvm, pos, 0) == -1) { 104 if (kvm_errstr != NULL) { 105 fprintf(stderr, "%s", kvm_errstr); 106 perror("lseek"); 107 } 108 return -1; 109 } 110 111 for (bufp = buffer, left = size; left > 0; bufp += r, left -= r) { 112 r = read(*kvm, bufp, left); 113#ifdef __osf__ 114 /* 115 * Tru64 returns "0" for successful operation, not the number 116 * of bytes read. 117 */ 118 if (r == 0) 119 r = left; 120#endif 121 if (r <= 0) 122 return -1; 123 } 124 return r; 125} 126#endif /* !defined(__sgi) && !defined(__hpux) && !defined(__osf__) */ 127 128int openkmem(kern, core) 129char *kern, *core; 130{ 131 kvm_f = kvm_open(kern, core, NULL, O_RDONLY, NULL); 132 if (kvm_f == NULL) 133 { 134 perror("openkmem:open"); 135 return -1; 136 } 137 return kvm_f != NULL; 138} 139 140int kmemcpy(buf, pos, n) 141register char *buf; 142long pos; 143register int n; 144{ 145 register int r; 146 147 if (!n) 148 return 0; 149 150 if (kvm_f == NULL) 151 if (openkmem(NULL, NULL) == -1) 152 return -1; 153 154 while ((r = kvm_read(kvm_f, pos, buf, n)) < n) 155 if (r <= 0) 156 { 157 fprintf(stderr, "pos=0x%lx ", (u_long)pos); 158 perror("kmemcpy:read"); 159 return -1; 160 } 161 else 162 { 163 buf += r; 164 pos += r; 165 n -= r; 166 } 167 return 0; 168} 169 170int kstrncpy(buf, pos, n) 171register char *buf; 172long pos; 173register int n; 174{ 175 register int r; 176 177 if (!n) 178 return 0; 179 180 if (kvm_f == NULL) 181 if (openkmem(NULL, NULL) == -1) 182 return -1; 183 184 while (n > 0) 185 { 186 r = kvm_read(kvm_f, pos, buf, 1); 187 if (r <= 0) 188 { 189 fprintf(stderr, "pos=0x%lx ", (u_long)pos); 190 perror("kmemcpy:read"); 191 return -1; 192 } 193 else 194 { 195 if (*buf == '\0') 196 break; 197 buf++; 198 pos++; 199 n--; 200 } 201 } 202 return 0; 203} 204