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