diff options
Diffstat (limited to 'lib/kmem.c')
-rw-r--r-- | lib/kmem.c | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/lib/kmem.c b/lib/kmem.c new file mode 100644 index 0000000..07830fb --- /dev/null +++ b/lib/kmem.c @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2000-2005 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. + */ + +#include <stdio.h> +#include <sys/param.h> +#include <sys/types.h> +#include <sys/uio.h> +#include <unistd.h> +#include <string.h> +#include <fcntl.h> +#include <sys/file.h> +#if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && !defined(linux) && !defined(_AIX51) +#include <kvm.h> +#endif +#include <fcntl.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <net/if.h> +#if __FreeBSD_version >= 300000 +# include <net/if_var.h> +#endif +#if defined(linux) || defined(__osf__) || defined(__sgi) || defined(__hpux) +# include <stdlib.h> +#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.3 2006/06/16 17:21:04 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) + 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; +} |