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