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