summaryrefslogtreecommitdiffstats
path: root/contrib/ipfilter/lib/kmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ipfilter/lib/kmem.c')
-rw-r--r--contrib/ipfilter/lib/kmem.c201
1 files changed, 201 insertions, 0 deletions
diff --git a/contrib/ipfilter/lib/kmem.c b/contrib/ipfilter/lib/kmem.c
new file mode 100644
index 0000000..d895baf
--- /dev/null
+++ b/contrib/ipfilter/lib/kmem.c
@@ -0,0 +1,201 @@
+/* $FreeBSD$ */
+
+/*
+ * Copyright (C) 2012 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 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$";
+#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;
+}
OpenPOWER on IntegriCloud