freebsd-skq/kmem.c
Cy Schubert f27f47054d As per the developers handbook (5.3.1 step 1), prepare the vendor trees for
import of new ipfilter vendor sources by flattening them.

To keep the tags consistent with dist, the tags are also flattened.

Approved by:	glebius (Mentor)
2013-07-19 05:41:57 +00:00

245 lines
4.3 KiB
C

/*
* Copyright (C) 1993-2002 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
/*
* kmemcpy() - copies n bytes from kernel memory into user buffer.
* returns 0 on success, -1 on error.
*/
#if defined(__sgi) && (IRIX > 602)
# include <sys/ptimers.h>
#endif
#include <stdio.h>
#include <sys/param.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/file.h>
#ifndef __sgi
#include <kvm.h>
#endif
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <net/if.h>
#if __FreeBSD_version >= 300000
# include <net/if_var.h>
#endif
#include "kmem.h"
#include "netinet/ip_compat.h"
#include "netinet/ip_fil.h"
#include "ipf.h"
#ifndef __STDC__
# define const
#endif
#if !defined(lint)
static const char sccsid[] = "@(#)kmem.c 1.4 1/12/96 (C) 1992 Darren Reed";
static const char rcsid[] = "@(#)$Id: kmem.c,v 2.2.2.18 2003/11/09 17:22:22 darrenr Exp $";
#endif
#ifdef __sgi
typedef int kvm_t;
static int kvm_fd = -1;
static char *kvm_errstr = NULL;
kvm_t *kvm_open(kernel, core, swap, mode, errstr)
char *kernel, *core, *swap;
int mode;
char *errstr;
{
kvm_errstr = errstr;
if (core == NULL)
core = "/dev/kmem";
kvm_fd = open(core, mode);
return (kvm_fd >= 0) ? (kvm_t *)&kvm_fd : NULL;
}
int kvm_read(kvm, pos, buffer, size)
kvm_t *kvm;
u_long pos;
char *buffer;
size_t size;
{
size_t left;
char *bufp;
int r;
if (lseek(*kvm, pos, 0) == -1) {
if (kvm_errstr != NULL) {
fprintf(stderr, "%s:", kvm_errstr);
perror("lseek");
}
return -1;
}
for (bufp = buffer, left = size; left > 0; bufp += r, left -= r) {
r = read(*kvm, bufp, 1);
if (r <= 0)
return -1;
}
return size;
}
#endif
static kvm_t *kvm_f = NULL;
int openkmem(kern, core)
char *kern, *core;
{
union {
int ui;
kvm_t *uk;
} k;
kvm_f = kvm_open(kern, core, NULL, O_RDONLY, NULL);
if (kvm_f == NULL)
{
perror("openkmem:open");
return -1;
}
k.uk = kvm_f;
return k.ui;
}
int kmemcpy(buf, pos, n)
register char *buf;
long pos;
register int n;
{
register int r;
if (!n)
return 0;
if (kvm_f == NULL)
if (openkmem(NULL, NULL) == -1)
return -1;
while ((r = kvm_read(kvm_f, pos, buf, (size_t)n)) < n)
if (r <= 0)
{
fprintf(stderr, "pos=0x%x ", (u_int)pos);
perror("kmemcpy:read");
return -1;
}
else
{
buf += r;
pos += r;
n -= r;
}
return 0;
}
int kstrncpy(buf, pos, n)
register char *buf;
long pos;
register int n;
{
register int r;
if (!n)
return 0;
if (kvm_f == NULL)
if (openkmem(NULL, NULL) == -1)
return -1;
while (n > 0)
{
r = kvm_read(kvm_f, pos, buf, (size_t)1);
if (r <= 0)
{
fprintf(stderr, "pos=0x%x ", (u_int)pos);
perror("kstrncpy:read");
return -1;
}
else
{
if (*buf == '\0')
break;
buf++;
pos++;
n--;
}
}
return 0;
}
/*
* Given a pointer to an interface in the kernel, return a pointer to a
* string which is the interface name.
*/
char *getifname(ptr)
void *ptr;
{
#if SOLARIS
char *ifname;
ill_t ill;
if (ptr == (void *)-1)
return "!";
if (ptr == NULL)
return "-";
if (kmemcpy((char *)&ill, (u_long)ptr, sizeof(ill)) == -1)
return "X";
ifname = malloc(ill.ill_name_length + 1);
if (kmemcpy(ifname, (u_long)ill.ill_name,
ill.ill_name_length) == -1)
return "X";
return ifname;
#else
# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
defined(__OpenBSD__) || \
(defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
#else
char buf[32];
int len;
# endif
struct ifnet netif;
if (ptr == (void *)-1)
return "!";
if (ptr == NULL)
return "-";
if (kmemcpy((char *)&netif, (u_long)ptr, sizeof(netif)) == -1)
return "X";
# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \
defined(__OpenBSD__) || \
(defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
return strdup(netif.if_xname);
# else
if (kstrncpy(buf, (u_long)netif.if_name, sizeof(buf)) == -1)
return "X";
if (netif.if_unit < 10)
len = 2;
else if (netif.if_unit < 1000)
len = 3;
else if (netif.if_unit < 10000)
len = 4;
else
len = 5;
buf[sizeof(buf) - len] = '\0';
sprintf(buf + strlen(buf), "%d", netif.if_unit % 10000);
return strdup(buf);
# endif
#endif
}