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
kvm_open(kernel,core,swap,mode,errstr)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
kvm_read(kvm,pos,buffer,size)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
openkmem(kern,core)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
kmemcpy(buf,pos,n)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
kstrncpy(buf,pos,n)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