xref: /illumos-gate/usr/src/cmd/ipf/lib/kmem.c (revision 1a2d662a91cee3bf82f41cd47c7ae6f3825d9db2)
1 /*
2  * Copyright (C) 1993-2001 by Darren Reed.
3  *
4  * See the IPFILTER.LICENCE file for details on licencing.
5  */
6 /*
7  * kmemcpy() - copies n bytes from kernel memory into user buffer.
8  * returns 0 on success, -1 on error.
9  */
10 
11 /*
12  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
13  * Use is subject to license terms.
14  */
15 
16 #include <stdio.h>
17 #include <sys/param.h>
18 #include <sys/types.h>
19 #include <sys/uio.h>
20 #include <unistd.h>
21 #include <string.h>
22 #include <fcntl.h>
23 #include <sys/file.h>
24 #if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && !defined(linux) && !defined(_AIX51)
25 #include <kvm.h>
26 #endif
27 #include <fcntl.h>
28 #include <sys/socket.h>
29 #include <sys/ioctl.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
32 #include <netinet/in_systm.h>
33 #include <netinet/ip.h>
34 #include <net/if.h>
35 #if __FreeBSD_version >= 300000
36 # include <net/if_var.h>
37 #endif
38 #if defined(linux) || defined(__osf__) || defined(__sgi) || defined(__hpux)
39 # include <stdlib.h>
40 #endif
41 
42 #include "kmem.h"
43 
44 #ifndef __STDC__
45 # define	const
46 #endif
47 
48 #if !defined(lint)
49 static const char sccsid[] = "@(#)kmem.c	1.4 1/12/96 (C) 1992 Darren Reed";
50 static const char rcsid[] = "@(#)$Id: kmem.c,v 1.16.2.2 2005/06/12 07:18:41 darrenr Exp $";
51 #endif
52 
53 
54 
55 #if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && \
56     !defined(linux) && !defined(_AIX51)
57 /*
58  * For all platforms where there is a libkvm and a kvm_t, we use that...
59  */
60 static	kvm_t	*kvm_f = NULL;
61 
62 #else
63 /*
64  *...and for the others (HP-UX, IRIX, Tru64), we have to provide our own.
65  */
66 
67 typedef	int *	kvm_t;
68 
69 static	kvm_t	kvm_f = NULL;
70 static	char	*kvm_errstr = NULL;
71 
72 kvm_t kvm_open __P((char *, char *, char *, int, char *));
73 int kvm_read __P((kvm_t, u_long, char *, size_t));
74 
75 kvm_t kvm_open(kernel, core, swap, mode, errstr)
76 char *kernel, *core, *swap;
77 int mode;
78 char *errstr;
79 {
80 	kvm_t k;
81 	int fd;
82 
83 	kvm_errstr = errstr;
84 
85 	if (core == NULL)
86 		core = "/dev/kmem";
87 
88 	fd = open(core, mode);
89 	if (fd == -1)
90 		return NULL;
91 	k = malloc(sizeof(*k));
92 	if (k == NULL) {
93 		close(fd);
94 		return NULL;
95 	}
96 	*k = fd;
97 	return k;
98 }
99 
100 int kvm_read(kvm, pos, buffer, size)
101 kvm_t kvm;
102 u_long pos;
103 char *buffer;
104 size_t size;
105 {
106 	int r = 0, left;
107 	char *bufp;
108 
109 	if (lseek(*kvm, pos, 0) == -1) {
110 		if (kvm_errstr != NULL) {
111 			fprintf(stderr, "%s", kvm_errstr);
112 			perror("lseek");
113 		}
114 		return -1;
115 	}
116 
117 	for (bufp = buffer, left = size; left > 0; bufp += r, left -= r) {
118 		r = read(*kvm, bufp, left);
119 #ifdef	__osf__
120 		/*
121 		 * Tru64 returns "0" for successful operation, not the number
122 		 * of bytes read.
123 		 */
124 		if (r == 0)
125 			r = left;
126 #endif
127 		if (r <= 0)
128 			return -1;
129 	}
130 	return r;
131 }
132 #endif /* !defined(__sgi) && !defined(__hpux) && !defined(__osf__) */
133 
134 int	openkmem(kern, core)
135 char	*kern, *core;
136 {
137 	kvm_f = kvm_open(kern, core, NULL, O_RDONLY, NULL);
138 	if (kvm_f == NULL)
139 	    {
140 		perror("openkmem:open");
141 		return -1;
142 	    }
143 	return kvm_f != NULL;
144 }
145 
146 int	kmemcpy(buf, pos, n)
147 register char	*buf;
148 long	pos;
149 register int	n;
150 {
151 	register int	r;
152 
153 	if (!n)
154 		return 0;
155 
156 	if (kvm_f == NULL)
157 		if (openkmem(NULL, NULL) == -1)
158 			return -1;
159 
160 	while ((r = kvm_read(kvm_f, pos, buf, n)) < n)
161 		if (r <= 0)
162 		    {
163 			fprintf(stderr, "pos=0x%lx ", (u_long)pos);
164 			perror("kmemcpy:read");
165 			return -1;
166 		    }
167 		else
168 		    {
169 			buf += r;
170 			pos += r;
171 			n -= r;
172 		    }
173 	return 0;
174 }
175 
176 int	kstrncpy(buf, pos, n)
177 register char	*buf;
178 long	pos;
179 register int	n;
180 {
181 	register int	r;
182 
183 	if (!n)
184 		return 0;
185 
186 	if (kvm_f == NULL)
187 		if (openkmem(NULL, NULL) == -1)
188 			return -1;
189 
190 	while (n > 0)
191 	    {
192 		r = kvm_read(kvm_f, pos, buf, 1);
193 		if (r <= 0)
194 		    {
195 			fprintf(stderr, "pos=0x%lx ", (u_long)pos);
196 			perror("kmemcpy:read");
197 			return -1;
198 		    }
199 		else
200 		    {
201 			if (*buf == '\0')
202 				break;
203 			buf++;
204 			pos++;
205 			n--;
206 		    }
207 	    }
208 	return 0;
209 }
210