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