kmem.c revision 145519
1250323Sdteske/* $FreeBSD: head/contrib/ipfilter/lib/kmem.c 145519 2005-04-25 18:20:15Z darrenr $ */ 2250323Sdteske 3250323Sdteske/* 4252980Sdteske * Copyright (C) 1993-2001 by Darren Reed. 5250323Sdteske * 6250323Sdteske * See the IPFILTER.LICENCE file for details on licencing. 7250323Sdteske */ 8250323Sdteske/* 9250323Sdteske * kmemcpy() - copies n bytes from kernel memory into user buffer. 10250323Sdteske * returns 0 on success, -1 on error. 11250323Sdteske */ 12250323Sdteske 13250323Sdteske#include <stdio.h> 14250323Sdteske#include <sys/param.h> 15250323Sdteske#include <sys/types.h> 16252987Sdteske#include <sys/uio.h> 17250323Sdteske#include <unistd.h> 18250323Sdteske#include <string.h> 19250323Sdteske#include <fcntl.h> 20252987Sdteske#include <sys/file.h> 21250323Sdteske#if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && !defined(linux) 22250323Sdteske#include <kvm.h> 23250323Sdteske#endif 24250323Sdteske#include <fcntl.h> 25250323Sdteske#include <sys/socket.h> 26250323Sdteske#include <sys/ioctl.h> 27250323Sdteske#include <netinet/in.h> 28250323Sdteske#include <arpa/inet.h> 29250323Sdteske#include <netinet/in_systm.h> 30250323Sdteske#include <netinet/ip.h> 31250323Sdteske#include <net/if.h> 32250323Sdteske#if __FreeBSD_version >= 300000 33250323Sdteske# include <net/if_var.h> 34250323Sdteske#endif 35252745Sdteske#if defined(linux) || defined(__osf__) || defined(__sgi) || defined(__hpux) 36252745Sdteske# include <stdlib.h> 37250323Sdteske#endif 38250323Sdteske 39252077Sdteske#include "kmem.h" 40250323Sdteske 41250323Sdteske#ifndef __STDC__ 42250323Sdteske# define const 43250323Sdteske#endif 44250323Sdteske 45250323Sdteske#if !defined(lint) 46250323Sdteskestatic const char sccsid[] = "@(#)kmem.c 1.4 1/12/96 (C) 1992 Darren Reed"; 47250323Sdteskestatic const char rcsid[] = "@(#)Id: kmem.c,v 1.16.2.1 2004/06/20 10:25:58 darrenr Exp"; 48250323Sdteske#endif 49250323Sdteske 50250323Sdteske 51250323Sdteske 52250323Sdteske#if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && !defined(linux) 53252740Sdteske/* 54252745Sdteske * For all platforms where there is a libkvm and a kvm_t, we use that... 55252745Sdteske */ 56257795Sdteskestatic kvm_t *kvm_f = NULL; 57252745Sdteske 58252745Sdteske#else 59252740Sdteske/* 60252740Sdteske *...and for the others (HP-UX, IRIX, Tru64), we have to provide our own. 61252745Sdteske */ 62252740Sdteske 63252740Sdtesketypedef int * kvm_t; 64250323Sdteske 65250323Sdteskestatic kvm_t kvm_f = NULL; 66250323Sdteskestatic char *kvm_errstr = NULL; 67250323Sdteske 68250323Sdteskekvm_t kvm_open __P((char *, char *, char *, int, char *)); 69250323Sdteskeint kvm_read __P((kvm_t, u_long, char *, size_t)); 70250323Sdteske 71250323Sdteskekvm_t kvm_open(kernel, core, swap, mode, errstr) 72250323Sdteskechar *kernel, *core, *swap; 73250323Sdteskeint mode; 74250323Sdteskechar *errstr; 75250323Sdteske{ 76250323Sdteske kvm_t k; 77250323Sdteske int fd; 78250323Sdteske 79250323Sdteske kvm_errstr = errstr; 80250323Sdteske 81250323Sdteske if (core == NULL) 82250323Sdteske core = "/dev/kmem"; 83250323Sdteske 84250323Sdteske fd = open(core, mode); 85250323Sdteske if (fd == -1) 86250323Sdteske return NULL; 87251355Sdteske k = malloc(sizeof(*k)); 88250323Sdteske if (k == NULL) 89250323Sdteske return NULL; 90251355Sdteske *k = fd; 91250323Sdteske return k; 92250323Sdteske} 93251355Sdteske 94250538Sdteskeint kvm_read(kvm, pos, buffer, size) 95250323Sdteskekvm_t kvm; 96250323Sdteskeu_long pos; 97250323Sdteskechar *buffer; 98250538Sdteskesize_t size; 99250538Sdteske{ 100250538Sdteske int r = 0, left; 101250538Sdteske char *bufp; 102251354Sdteske 103250323Sdteske if (lseek(*kvm, pos, 0) == -1) { 104250323Sdteske if (kvm_errstr != NULL) { 105250323Sdteske fprintf(stderr, "%s", kvm_errstr); 106250538Sdteske perror("lseek"); 107250538Sdteske } 108250538Sdteske return -1; 109250538Sdteske } 110251354Sdteske 111250323Sdteske for (bufp = buffer, left = size; left > 0; bufp += r, left -= r) { 112251354Sdteske r = read(*kvm, bufp, left); 113251355Sdteske#ifdef __osf__ 114250538Sdteske /* 115250323Sdteske * Tru64 returns "0" for successful operation, not the number 116250323Sdteske * of bytes read. 117251355Sdteske */ 118250323Sdteske if (r == 0) 119250323Sdteske r = left; 120250323Sdteske#endif 121250323Sdteske if (r <= 0) 122250323Sdteske return -1; 123250323Sdteske } 124250323Sdteske return r; 125250323Sdteske} 126250323Sdteske#endif /* !defined(__sgi) && !defined(__hpux) && !defined(__osf__) */ 127250323Sdteske 128250323Sdteskeint openkmem(kern, core) 129250323Sdteskechar *kern, *core; 130250323Sdteske{ 131250323Sdteske kvm_f = kvm_open(kern, core, NULL, O_RDONLY, NULL); 132250323Sdteske if (kvm_f == NULL) 133250323Sdteske { 134250323Sdteske perror("openkmem:open"); 135256181Sdteske return -1; 136250323Sdteske } 137250323Sdteske return kvm_f != NULL; 138252771Sdteske} 139250323Sdteske 140250323Sdteskeint kmemcpy(buf, pos, n) 141250323Sdteskeregister char *buf; 142250323Sdteskelong pos; 143250323Sdteskeregister int n; 144250323Sdteske{ 145250323Sdteske register int r; 146250323Sdteske 147250323Sdteske if (!n) 148250323Sdteske return 0; 149250323Sdteske 150250323Sdteske if (kvm_f == NULL) 151250323Sdteske if (openkmem(NULL, NULL) == -1) 152250323Sdteske return -1; 153250323Sdteske 154250323Sdteske while ((r = kvm_read(kvm_f, pos, buf, n)) < n) 155250323Sdteske if (r <= 0) 156250323Sdteske { 157250323Sdteske fprintf(stderr, "pos=0x%lx ", (u_long)pos); 158250323Sdteske perror("kmemcpy:read"); 159250323Sdteske return -1; 160250323Sdteske } 161252771Sdteske else 162250323Sdteske { 163250323Sdteske buf += r; 164250323Sdteske pos += r; 165250323Sdteske n -= r; 166250323Sdteske } 167257795Sdteske return 0; 168250323Sdteske} 169250323Sdteske 170250323Sdteskeint kstrncpy(buf, pos, n) 171250323Sdteskeregister char *buf; 172257795Sdteskelong pos; 173257795Sdteskeregister int n; 174250323Sdteske{ 175250323Sdteske register int r; 176250323Sdteske 177250323Sdteske if (!n) 178250323Sdteske return 0; 179250323Sdteske 180250323Sdteske if (kvm_f == NULL) 181250323Sdteske if (openkmem(NULL, NULL) == -1) 182250323Sdteske return -1; 183250323Sdteske 184250323Sdteske while (n > 0) 185250323Sdteske { 186250323Sdteske r = kvm_read(kvm_f, pos, buf, 1); 187250323Sdteske if (r <= 0) 188250323Sdteske { 189250323Sdteske fprintf(stderr, "pos=0x%lx ", (u_long)pos); 190250323Sdteske perror("kmemcpy:read"); 191250323Sdteske return -1; 192250323Sdteske } 193250323Sdteske else 194250323Sdteske { 195250323Sdteske if (*buf == '\0') 196250323Sdteske break; 197250323Sdteske buf++; 198250323Sdteske pos++; 199250323Sdteske n--; 200250323Sdteske } 201250323Sdteske } 202250323Sdteske return 0; 203250323Sdteske} 204250323Sdteske