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*ab25eeb5Syz155240 * 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*ab25eeb5Syz155240 #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*ab25eeb5Syz155240 #if defined(linux) || defined(__osf__) || defined(__sgi) || defined(__hpux)
41*ab25eeb5Syz155240 # include <stdlib.h>
42*ab25eeb5Syz155240 #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*ab25eeb5Syz155240 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*ab25eeb5Syz155240 #if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && \
58*ab25eeb5Syz155240 !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*ab25eeb5Syz155240 typedef int * kvm_t;
707c478bd9Sstevel@tonic-gate
71*ab25eeb5Syz155240 static kvm_t kvm_f = NULL;
727c478bd9Sstevel@tonic-gate static char *kvm_errstr = NULL;
737c478bd9Sstevel@tonic-gate
74*ab25eeb5Syz155240 kvm_t kvm_open __P((char *, char *, char *, int, char *));
75*ab25eeb5Syz155240 int kvm_read __P((kvm_t, u_long, char *, size_t));
76*ab25eeb5Syz155240
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*ab25eeb5Syz155240 kvm_t k;
83*ab25eeb5Syz155240 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*ab25eeb5Syz155240 if (fd == -1)
92*ab25eeb5Syz155240 return NULL;
93*ab25eeb5Syz155240 k = malloc(sizeof(*k));
94*ab25eeb5Syz155240 if (k == NULL) {
95*ab25eeb5Syz155240 close(fd);
96*ab25eeb5Syz155240 return NULL;
97*ab25eeb5Syz155240 }
98*ab25eeb5Syz155240 *k = fd;
99*ab25eeb5Syz155240 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*ab25eeb5Syz155240 int r = 0, left;
1097c478bd9Sstevel@tonic-gate char *bufp;
1107c478bd9Sstevel@tonic-gate
111*ab25eeb5Syz155240 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*ab25eeb5Syz155240 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*ab25eeb5Syz155240 if (r == 0)
127*ab25eeb5Syz155240 r = left;
128*ab25eeb5Syz155240 #endif
1297c478bd9Sstevel@tonic-gate if (r <= 0)
1307c478bd9Sstevel@tonic-gate return -1;
1317c478bd9Sstevel@tonic-gate }
132*ab25eeb5Syz155240 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*ab25eeb5Syz155240 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*ab25eeb5Syz155240 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