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