xref: /illumos-gate/usr/src/cmd/ipf/lib/common/kmem.c (revision ab25eeb5)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * Copyright (C) 1993-2001 by Darren Reed.
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * See the IPFILTER.LICENCE file for details on licencing.
57c478bd9Sstevel@tonic-gate  */
67c478bd9Sstevel@tonic-gate /*
77c478bd9Sstevel@tonic-gate  * kmemcpy() - copies n bytes from kernel memory into user buffer.
87c478bd9Sstevel@tonic-gate  * returns 0 on success, -1 on error.
97c478bd9Sstevel@tonic-gate  */
107c478bd9Sstevel@tonic-gate 
117c478bd9Sstevel@tonic-gate /*
12*ab25eeb5Syz  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
137c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
147c478bd9Sstevel@tonic-gate  */
157c478bd9Sstevel@tonic-gate 
167c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
177c478bd9Sstevel@tonic-gate 
187c478bd9Sstevel@tonic-gate #include <stdio.h>
197c478bd9Sstevel@tonic-gate #include <sys/param.h>
207c478bd9Sstevel@tonic-gate #include <sys/types.h>
217c478bd9Sstevel@tonic-gate #include <sys/uio.h>
227c478bd9Sstevel@tonic-gate #include <unistd.h>
237c478bd9Sstevel@tonic-gate #include <string.h>
247c478bd9Sstevel@tonic-gate #include <fcntl.h>
257c478bd9Sstevel@tonic-gate #include <sys/file.h>
26*ab25eeb5Syz #if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && !defined(linux) && !defined(_AIX51)
277c478bd9Sstevel@tonic-gate #include <kvm.h>
287c478bd9Sstevel@tonic-gate #endif
297c478bd9Sstevel@tonic-gate #include <fcntl.h>
307c478bd9Sstevel@tonic-gate #include <sys/socket.h>
317c478bd9Sstevel@tonic-gate #include <sys/ioctl.h>
327c478bd9Sstevel@tonic-gate #include <netinet/in.h>
337c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
347c478bd9Sstevel@tonic-gate #include <netinet/in_systm.h>
357c478bd9Sstevel@tonic-gate #include <netinet/ip.h>
367c478bd9Sstevel@tonic-gate #include <net/if.h>
377c478bd9Sstevel@tonic-gate #if __FreeBSD_version >= 300000
387c478bd9Sstevel@tonic-gate # include <net/if_var.h>
397c478bd9Sstevel@tonic-gate #endif
40*ab25eeb5Syz #if defined(linux) || defined(__osf__) || defined(__sgi) || defined(__hpux)
41*ab25eeb5Syz # include <stdlib.h>
42*ab25eeb5Syz #endif
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate #include "kmem.h"
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate #ifndef __STDC__
477c478bd9Sstevel@tonic-gate # define	const
487c478bd9Sstevel@tonic-gate #endif
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate #if !defined(lint)
517c478bd9Sstevel@tonic-gate static const char sccsid[] = "@(#)kmem.c	1.4 1/12/96 (C) 1992 Darren Reed";
52*ab25eeb5Syz static const char rcsid[] = "@(#)$Id: kmem.c,v 1.16.2.2 2005/06/12 07:18:41 darrenr Exp $";
537c478bd9Sstevel@tonic-gate #endif
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate 
57*ab25eeb5Syz #if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && \
58*ab25eeb5Syz     !defined(linux) && !defined(_AIX51)
597c478bd9Sstevel@tonic-gate /*
607c478bd9Sstevel@tonic-gate  * For all platforms where there is a libkvm and a kvm_t, we use that...
617c478bd9Sstevel@tonic-gate  */
627c478bd9Sstevel@tonic-gate static	kvm_t	*kvm_f = NULL;
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate #else
657c478bd9Sstevel@tonic-gate /*
667c478bd9Sstevel@tonic-gate  *...and for the others (HP-UX, IRIX, Tru64), we have to provide our own.
677c478bd9Sstevel@tonic-gate  */
687c478bd9Sstevel@tonic-gate 
69*ab25eeb5Syz typedef	int *	kvm_t;
707c478bd9Sstevel@tonic-gate 
71*ab25eeb5Syz static	kvm_t	kvm_f = NULL;
727c478bd9Sstevel@tonic-gate static	char	*kvm_errstr = NULL;
737c478bd9Sstevel@tonic-gate 
74*ab25eeb5Syz kvm_t kvm_open __P((char *, char *, char *, int, char *));
75*ab25eeb5Syz int kvm_read __P((kvm_t, u_long, char *, size_t));
76*ab25eeb5Syz 
kvm_open(kernel,core,swap,mode,errstr)777c478bd9Sstevel@tonic-gate kvm_t kvm_open(kernel, core, swap, mode, errstr)
787c478bd9Sstevel@tonic-gate char *kernel, *core, *swap;
797c478bd9Sstevel@tonic-gate int mode;
807c478bd9Sstevel@tonic-gate char *errstr;
817c478bd9Sstevel@tonic-gate {
82*ab25eeb5Syz 	kvm_t k;
83*ab25eeb5Syz 	int fd;
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate 	kvm_errstr = errstr;
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate 	if (core == NULL)
887c478bd9Sstevel@tonic-gate 		core = "/dev/kmem";
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate 	fd = open(core, mode);
91*ab25eeb5Syz 	if (fd == -1)
92*ab25eeb5Syz 		return NULL;
93*ab25eeb5Syz 	k = malloc(sizeof(*k));
94*ab25eeb5Syz 	if (k == NULL) {
95*ab25eeb5Syz 		close(fd);
96*ab25eeb5Syz 		return NULL;
97*ab25eeb5Syz 	}
98*ab25eeb5Syz 	*k = fd;
99*ab25eeb5Syz 	return k;
1007c478bd9Sstevel@tonic-gate }
1017c478bd9Sstevel@tonic-gate 
kvm_read(kvm,pos,buffer,size)1027c478bd9Sstevel@tonic-gate int kvm_read(kvm, pos, buffer, size)
1037c478bd9Sstevel@tonic-gate kvm_t kvm;
1047c478bd9Sstevel@tonic-gate u_long pos;
1057c478bd9Sstevel@tonic-gate char *buffer;
1067c478bd9Sstevel@tonic-gate size_t size;
1077c478bd9Sstevel@tonic-gate {
108*ab25eeb5Syz 	int r = 0, left;
1097c478bd9Sstevel@tonic-gate 	char *bufp;
1107c478bd9Sstevel@tonic-gate 
111*ab25eeb5Syz 	if (lseek(*kvm, pos, 0) == -1) {
1127c478bd9Sstevel@tonic-gate 		if (kvm_errstr != NULL) {
1137c478bd9Sstevel@tonic-gate 			fprintf(stderr, "%s", kvm_errstr);
1147c478bd9Sstevel@tonic-gate 			perror("lseek");
1157c478bd9Sstevel@tonic-gate 		}
1167c478bd9Sstevel@tonic-gate 		return -1;
1177c478bd9Sstevel@tonic-gate 	}
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate 	for (bufp = buffer, left = size; left > 0; bufp += r, left -= r) {
120*ab25eeb5Syz 		r = read(*kvm, bufp, left);
1217c478bd9Sstevel@tonic-gate #ifdef	__osf__
1227c478bd9Sstevel@tonic-gate 		/*
1237c478bd9Sstevel@tonic-gate 		 * Tru64 returns "0" for successful operation, not the number
1247c478bd9Sstevel@tonic-gate 		 * of bytes read.
1257c478bd9Sstevel@tonic-gate 		 */
126*ab25eeb5Syz 		if (r == 0)
127*ab25eeb5Syz 			r = left;
128*ab25eeb5Syz #endif
1297c478bd9Sstevel@tonic-gate 		if (r <= 0)
1307c478bd9Sstevel@tonic-gate 			return -1;
1317c478bd9Sstevel@tonic-gate 	}
132*ab25eeb5Syz 	return r;
1337c478bd9Sstevel@tonic-gate }
1347c478bd9Sstevel@tonic-gate #endif /* !defined(__sgi) && !defined(__hpux) && !defined(__osf__) */
1357c478bd9Sstevel@tonic-gate 
openkmem(kern,core)1367c478bd9Sstevel@tonic-gate int	openkmem(kern, core)
1377c478bd9Sstevel@tonic-gate char	*kern, *core;
1387c478bd9Sstevel@tonic-gate {
1397c478bd9Sstevel@tonic-gate 	kvm_f = kvm_open(kern, core, NULL, O_RDONLY, NULL);
1407c478bd9Sstevel@tonic-gate 	if (kvm_f == NULL)
1417c478bd9Sstevel@tonic-gate 	    {
1427c478bd9Sstevel@tonic-gate 		perror("openkmem:open");
1437c478bd9Sstevel@tonic-gate 		return -1;
1447c478bd9Sstevel@tonic-gate 	    }
145*ab25eeb5Syz 	return kvm_f != NULL;
1467c478bd9Sstevel@tonic-gate }
1477c478bd9Sstevel@tonic-gate 
kmemcpy(buf,pos,n)1487c478bd9Sstevel@tonic-gate int	kmemcpy(buf, pos, n)
1497c478bd9Sstevel@tonic-gate register char	*buf;
1507c478bd9Sstevel@tonic-gate long	pos;
1517c478bd9Sstevel@tonic-gate register int	n;
1527c478bd9Sstevel@tonic-gate {
1537c478bd9Sstevel@tonic-gate 	register int	r;
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate 	if (!n)
1567c478bd9Sstevel@tonic-gate 		return 0;
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 	if (kvm_f == NULL)
1597c478bd9Sstevel@tonic-gate 		if (openkmem(NULL, NULL) == -1)
1607c478bd9Sstevel@tonic-gate 			return -1;
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate 	while ((r = kvm_read(kvm_f, pos, buf, n)) < n)
1637c478bd9Sstevel@tonic-gate 		if (r <= 0)
1647c478bd9Sstevel@tonic-gate 		    {
1657c478bd9Sstevel@tonic-gate 			fprintf(stderr, "pos=0x%lx ", (u_long)pos);
1667c478bd9Sstevel@tonic-gate 			perror("kmemcpy:read");
1677c478bd9Sstevel@tonic-gate 			return -1;
1687c478bd9Sstevel@tonic-gate 		    }
1697c478bd9Sstevel@tonic-gate 		else
1707c478bd9Sstevel@tonic-gate 		    {
1717c478bd9Sstevel@tonic-gate 			buf += r;
1727c478bd9Sstevel@tonic-gate 			pos += r;
1737c478bd9Sstevel@tonic-gate 			n -= r;
1747c478bd9Sstevel@tonic-gate 		    }
1757c478bd9Sstevel@tonic-gate 	return 0;
1767c478bd9Sstevel@tonic-gate }
1777c478bd9Sstevel@tonic-gate 
kstrncpy(buf,pos,n)1787c478bd9Sstevel@tonic-gate int	kstrncpy(buf, pos, n)
1797c478bd9Sstevel@tonic-gate register char	*buf;
1807c478bd9Sstevel@tonic-gate long	pos;
1817c478bd9Sstevel@tonic-gate register int	n;
1827c478bd9Sstevel@tonic-gate {
1837c478bd9Sstevel@tonic-gate 	register int	r;
1847c478bd9Sstevel@tonic-gate 
1857c478bd9Sstevel@tonic-gate 	if (!n)
1867c478bd9Sstevel@tonic-gate 		return 0;
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate 	if (kvm_f == NULL)
1897c478bd9Sstevel@tonic-gate 		if (openkmem(NULL, NULL) == -1)
1907c478bd9Sstevel@tonic-gate 			return -1;
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate 	while (n > 0)
1937c478bd9Sstevel@tonic-gate 	    {
1947c478bd9Sstevel@tonic-gate 		r = kvm_read(kvm_f, pos, buf, 1);
1957c478bd9Sstevel@tonic-gate 		if (r <= 0)
1967c478bd9Sstevel@tonic-gate 		    {
1977c478bd9Sstevel@tonic-gate 			fprintf(stderr, "pos=0x%lx ", (u_long)pos);
198*ab25eeb5Syz 			perror("kmemcpy:read");
1997c478bd9Sstevel@tonic-gate 			return -1;
2007c478bd9Sstevel@tonic-gate 		    }
2017c478bd9Sstevel@tonic-gate 		else
2027c478bd9Sstevel@tonic-gate 		    {
2037c478bd9Sstevel@tonic-gate 			if (*buf == '\0')
2047c478bd9Sstevel@tonic-gate 				break;
2057c478bd9Sstevel@tonic-gate 			buf++;
2067c478bd9Sstevel@tonic-gate 			pos++;
2077c478bd9Sstevel@tonic-gate 			n--;
2087c478bd9Sstevel@tonic-gate 		    }
2097c478bd9Sstevel@tonic-gate 	    }
2107c478bd9Sstevel@tonic-gate 	return 0;
2117c478bd9Sstevel@tonic-gate }
212