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