kmem.c revision 145511
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