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