xref: /onnv-gate/usr/src/cmd/ipf/lib/common/kmem.c (revision 2393:76e0289ce525)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * Copyright (C) 1993-2001 by Darren Reed.
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * See the IPFILTER.LICENCE file for details on licencing.
50Sstevel@tonic-gate  */
60Sstevel@tonic-gate /*
70Sstevel@tonic-gate  * kmemcpy() - copies n bytes from kernel memory into user buffer.
80Sstevel@tonic-gate  * returns 0 on success, -1 on error.
90Sstevel@tonic-gate  */
100Sstevel@tonic-gate 
110Sstevel@tonic-gate /*
12*2393Syz155240  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
130Sstevel@tonic-gate  * Use is subject to license terms.
140Sstevel@tonic-gate  */
150Sstevel@tonic-gate 
160Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
170Sstevel@tonic-gate 
180Sstevel@tonic-gate #include <stdio.h>
190Sstevel@tonic-gate #include <sys/param.h>
200Sstevel@tonic-gate #include <sys/types.h>
210Sstevel@tonic-gate #include <sys/uio.h>
220Sstevel@tonic-gate #include <unistd.h>
230Sstevel@tonic-gate #include <string.h>
240Sstevel@tonic-gate #include <fcntl.h>
250Sstevel@tonic-gate #include <sys/file.h>
26*2393Syz155240 #if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && !defined(linux) && !defined(_AIX51)
270Sstevel@tonic-gate #include <kvm.h>
280Sstevel@tonic-gate #endif
290Sstevel@tonic-gate #include <fcntl.h>
300Sstevel@tonic-gate #include <sys/socket.h>
310Sstevel@tonic-gate #include <sys/ioctl.h>
320Sstevel@tonic-gate #include <netinet/in.h>
330Sstevel@tonic-gate #include <arpa/inet.h>
340Sstevel@tonic-gate #include <netinet/in_systm.h>
350Sstevel@tonic-gate #include <netinet/ip.h>
360Sstevel@tonic-gate #include <net/if.h>
370Sstevel@tonic-gate #if __FreeBSD_version >= 300000
380Sstevel@tonic-gate # include <net/if_var.h>
390Sstevel@tonic-gate #endif
40*2393Syz155240 #if defined(linux) || defined(__osf__) || defined(__sgi) || defined(__hpux)
41*2393Syz155240 # include <stdlib.h>
42*2393Syz155240 #endif
430Sstevel@tonic-gate 
440Sstevel@tonic-gate #include "kmem.h"
450Sstevel@tonic-gate 
460Sstevel@tonic-gate #ifndef __STDC__
470Sstevel@tonic-gate # define	const
480Sstevel@tonic-gate #endif
490Sstevel@tonic-gate 
500Sstevel@tonic-gate #if !defined(lint)
510Sstevel@tonic-gate static const char sccsid[] = "@(#)kmem.c	1.4 1/12/96 (C) 1992 Darren Reed";
52*2393Syz155240 static const char rcsid[] = "@(#)$Id: kmem.c,v 1.16.2.2 2005/06/12 07:18:41 darrenr Exp $";
530Sstevel@tonic-gate #endif
540Sstevel@tonic-gate 
550Sstevel@tonic-gate 
560Sstevel@tonic-gate 
57*2393Syz155240 #if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && \
58*2393Syz155240     !defined(linux) && !defined(_AIX51)
590Sstevel@tonic-gate /*
600Sstevel@tonic-gate  * For all platforms where there is a libkvm and a kvm_t, we use that...
610Sstevel@tonic-gate  */
620Sstevel@tonic-gate static	kvm_t	*kvm_f = NULL;
630Sstevel@tonic-gate 
640Sstevel@tonic-gate #else
650Sstevel@tonic-gate /*
660Sstevel@tonic-gate  *...and for the others (HP-UX, IRIX, Tru64), we have to provide our own.
670Sstevel@tonic-gate  */
680Sstevel@tonic-gate 
69*2393Syz155240 typedef	int *	kvm_t;
700Sstevel@tonic-gate 
71*2393Syz155240 static	kvm_t	kvm_f = NULL;
720Sstevel@tonic-gate static	char	*kvm_errstr = NULL;
730Sstevel@tonic-gate 
74*2393Syz155240 kvm_t kvm_open __P((char *, char *, char *, int, char *));
75*2393Syz155240 int kvm_read __P((kvm_t, u_long, char *, size_t));
76*2393Syz155240 
kvm_open(kernel,core,swap,mode,errstr)770Sstevel@tonic-gate kvm_t kvm_open(kernel, core, swap, mode, errstr)
780Sstevel@tonic-gate char *kernel, *core, *swap;
790Sstevel@tonic-gate int mode;
800Sstevel@tonic-gate char *errstr;
810Sstevel@tonic-gate {
82*2393Syz155240 	kvm_t k;
83*2393Syz155240 	int fd;
840Sstevel@tonic-gate 
850Sstevel@tonic-gate 	kvm_errstr = errstr;
860Sstevel@tonic-gate 
870Sstevel@tonic-gate 	if (core == NULL)
880Sstevel@tonic-gate 		core = "/dev/kmem";
890Sstevel@tonic-gate 
900Sstevel@tonic-gate 	fd = open(core, mode);
91*2393Syz155240 	if (fd == -1)
92*2393Syz155240 		return NULL;
93*2393Syz155240 	k = malloc(sizeof(*k));
94*2393Syz155240 	if (k == NULL) {
95*2393Syz155240 		close(fd);
96*2393Syz155240 		return NULL;
97*2393Syz155240 	}
98*2393Syz155240 	*k = fd;
99*2393Syz155240 	return k;
1000Sstevel@tonic-gate }
1010Sstevel@tonic-gate 
kvm_read(kvm,pos,buffer,size)1020Sstevel@tonic-gate int kvm_read(kvm, pos, buffer, size)
1030Sstevel@tonic-gate kvm_t kvm;
1040Sstevel@tonic-gate u_long pos;
1050Sstevel@tonic-gate char *buffer;
1060Sstevel@tonic-gate size_t size;
1070Sstevel@tonic-gate {
108*2393Syz155240 	int r = 0, left;
1090Sstevel@tonic-gate 	char *bufp;
1100Sstevel@tonic-gate 
111*2393Syz155240 	if (lseek(*kvm, pos, 0) == -1) {
1120Sstevel@tonic-gate 		if (kvm_errstr != NULL) {
1130Sstevel@tonic-gate 			fprintf(stderr, "%s", kvm_errstr);
1140Sstevel@tonic-gate 			perror("lseek");
1150Sstevel@tonic-gate 		}
1160Sstevel@tonic-gate 		return -1;
1170Sstevel@tonic-gate 	}
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate 	for (bufp = buffer, left = size; left > 0; bufp += r, left -= r) {
120*2393Syz155240 		r = read(*kvm, bufp, left);
1210Sstevel@tonic-gate #ifdef	__osf__
1220Sstevel@tonic-gate 		/*
1230Sstevel@tonic-gate 		 * Tru64 returns "0" for successful operation, not the number
1240Sstevel@tonic-gate 		 * of bytes read.
1250Sstevel@tonic-gate 		 */
126*2393Syz155240 		if (r == 0)
127*2393Syz155240 			r = left;
128*2393Syz155240 #endif
1290Sstevel@tonic-gate 		if (r <= 0)
1300Sstevel@tonic-gate 			return -1;
1310Sstevel@tonic-gate 	}
132*2393Syz155240 	return r;
1330Sstevel@tonic-gate }
1340Sstevel@tonic-gate #endif /* !defined(__sgi) && !defined(__hpux) && !defined(__osf__) */
1350Sstevel@tonic-gate 
openkmem(kern,core)1360Sstevel@tonic-gate int	openkmem(kern, core)
1370Sstevel@tonic-gate char	*kern, *core;
1380Sstevel@tonic-gate {
1390Sstevel@tonic-gate 	kvm_f = kvm_open(kern, core, NULL, O_RDONLY, NULL);
1400Sstevel@tonic-gate 	if (kvm_f == NULL)
1410Sstevel@tonic-gate 	    {
1420Sstevel@tonic-gate 		perror("openkmem:open");
1430Sstevel@tonic-gate 		return -1;
1440Sstevel@tonic-gate 	    }
145*2393Syz155240 	return kvm_f != NULL;
1460Sstevel@tonic-gate }
1470Sstevel@tonic-gate 
kmemcpy(buf,pos,n)1480Sstevel@tonic-gate int	kmemcpy(buf, pos, n)
1490Sstevel@tonic-gate register char	*buf;
1500Sstevel@tonic-gate long	pos;
1510Sstevel@tonic-gate register int	n;
1520Sstevel@tonic-gate {
1530Sstevel@tonic-gate 	register int	r;
1540Sstevel@tonic-gate 
1550Sstevel@tonic-gate 	if (!n)
1560Sstevel@tonic-gate 		return 0;
1570Sstevel@tonic-gate 
1580Sstevel@tonic-gate 	if (kvm_f == NULL)
1590Sstevel@tonic-gate 		if (openkmem(NULL, NULL) == -1)
1600Sstevel@tonic-gate 			return -1;
1610Sstevel@tonic-gate 
1620Sstevel@tonic-gate 	while ((r = kvm_read(kvm_f, pos, buf, n)) < n)
1630Sstevel@tonic-gate 		if (r <= 0)
1640Sstevel@tonic-gate 		    {
1650Sstevel@tonic-gate 			fprintf(stderr, "pos=0x%lx ", (u_long)pos);
1660Sstevel@tonic-gate 			perror("kmemcpy:read");
1670Sstevel@tonic-gate 			return -1;
1680Sstevel@tonic-gate 		    }
1690Sstevel@tonic-gate 		else
1700Sstevel@tonic-gate 		    {
1710Sstevel@tonic-gate 			buf += r;
1720Sstevel@tonic-gate 			pos += r;
1730Sstevel@tonic-gate 			n -= r;
1740Sstevel@tonic-gate 		    }
1750Sstevel@tonic-gate 	return 0;
1760Sstevel@tonic-gate }
1770Sstevel@tonic-gate 
kstrncpy(buf,pos,n)1780Sstevel@tonic-gate int	kstrncpy(buf, pos, n)
1790Sstevel@tonic-gate register char	*buf;
1800Sstevel@tonic-gate long	pos;
1810Sstevel@tonic-gate register int	n;
1820Sstevel@tonic-gate {
1830Sstevel@tonic-gate 	register int	r;
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate 	if (!n)
1860Sstevel@tonic-gate 		return 0;
1870Sstevel@tonic-gate 
1880Sstevel@tonic-gate 	if (kvm_f == NULL)
1890Sstevel@tonic-gate 		if (openkmem(NULL, NULL) == -1)
1900Sstevel@tonic-gate 			return -1;
1910Sstevel@tonic-gate 
1920Sstevel@tonic-gate 	while (n > 0)
1930Sstevel@tonic-gate 	    {
1940Sstevel@tonic-gate 		r = kvm_read(kvm_f, pos, buf, 1);
1950Sstevel@tonic-gate 		if (r <= 0)
1960Sstevel@tonic-gate 		    {
1970Sstevel@tonic-gate 			fprintf(stderr, "pos=0x%lx ", (u_long)pos);
198*2393Syz155240 			perror("kmemcpy:read");
1990Sstevel@tonic-gate 			return -1;
2000Sstevel@tonic-gate 		    }
2010Sstevel@tonic-gate 		else
2020Sstevel@tonic-gate 		    {
2030Sstevel@tonic-gate 			if (*buf == '\0')
2040Sstevel@tonic-gate 				break;
2050Sstevel@tonic-gate 			buf++;
2060Sstevel@tonic-gate 			pos++;
2070Sstevel@tonic-gate 			n--;
2080Sstevel@tonic-gate 		    }
2090Sstevel@tonic-gate 	    }
2100Sstevel@tonic-gate 	return 0;
2110Sstevel@tonic-gate }
212