/* * Copyright (C) 1993-2001 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ /* * kmemcpy() - copies n bytes from kernel memory into user buffer. * returns 0 on success, -1 on error. */ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include #include #include #include #include #include #if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && !defined(linux) && !defined(_AIX51) #include #endif #include #include #include #include #include #include #include #include #if __FreeBSD_version >= 300000 # include #endif #if defined(linux) || defined(__osf__) || defined(__sgi) || defined(__hpux) # include #endif #include "kmem.h" #ifndef __STDC__ # define const #endif #if !defined(lint) static const char sccsid[] = "@(#)kmem.c 1.4 1/12/96 (C) 1992 Darren Reed"; static const char rcsid[] = "@(#)$Id: kmem.c,v 1.16.2.2 2005/06/12 07:18:41 darrenr Exp $"; #endif #if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && \ !defined(linux) && !defined(_AIX51) /* * For all platforms where there is a libkvm and a kvm_t, we use that... */ static kvm_t *kvm_f = NULL; #else /* *...and for the others (HP-UX, IRIX, Tru64), we have to provide our own. */ typedef int * kvm_t; static kvm_t kvm_f = NULL; static char *kvm_errstr = NULL; kvm_t kvm_open __P((char *, char *, char *, int, char *)); int kvm_read __P((kvm_t, u_long, char *, size_t)); kvm_t kvm_open(kernel, core, swap, mode, errstr) char *kernel, *core, *swap; int mode; char *errstr; { kvm_t k; int fd; kvm_errstr = errstr; if (core == NULL) core = "/dev/kmem"; fd = open(core, mode); if (fd == -1) return NULL; k = malloc(sizeof(*k)); if (k == NULL) { close(fd); return NULL; } *k = fd; return k; } int kvm_read(kvm, pos, buffer, size) kvm_t kvm; u_long pos; char *buffer; size_t size; { int r = 0, left; char *bufp; if (lseek(*kvm, pos, 0) == -1) { if (kvm_errstr != NULL) { fprintf(stderr, "%s", kvm_errstr); perror("lseek"); } return -1; } for (bufp = buffer, left = size; left > 0; bufp += r, left -= r) { r = read(*kvm, bufp, left); #ifdef __osf__ /* * Tru64 returns "0" for successful operation, not the number * of bytes read. */ if (r == 0) r = left; #endif if (r <= 0) return -1; } return r; } #endif /* !defined(__sgi) && !defined(__hpux) && !defined(__osf__) */ int openkmem(kern, core) char *kern, *core; { kvm_f = kvm_open(kern, core, NULL, O_RDONLY, NULL); if (kvm_f == NULL) { perror("openkmem:open"); return -1; } return kvm_f != NULL; } int kmemcpy(buf, pos, n) register char *buf; long pos; register int n; { register int r; if (!n) return 0; if (kvm_f == NULL) if (openkmem(NULL, NULL) == -1) return -1; while ((r = kvm_read(kvm_f, pos, buf, n)) < n) if (r <= 0) { fprintf(stderr, "pos=0x%lx ", (u_long)pos); perror("kmemcpy:read"); return -1; } else { buf += r; pos += r; n -= r; } return 0; } int kstrncpy(buf, pos, n) register char *buf; long pos; register int n; { register int r; if (!n) return 0; if (kvm_f == NULL) if (openkmem(NULL, NULL) == -1) return -1; while (n > 0) { r = kvm_read(kvm_f, pos, buf, 1); if (r <= 0) { fprintf(stderr, "pos=0x%lx ", (u_long)pos); perror("kmemcpy:read"); return -1; } else { if (*buf == '\0') break; buf++; pos++; n--; } } return 0; }