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