Use sysctl to fetch AF_LOCAL PCB lists if reading live kernel.
This commit is contained in:
parent
f6c9a2641f
commit
4c70438790
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: unix.c,v 1.23 2005/03/04 03:59:07 atatat Exp $ */
|
||||
/* $NetBSD: unix.c,v 1.24 2005/09/04 18:59:57 elad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1983, 1988, 1993
|
||||
@ -34,7 +34,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "from: @(#)unix.c 8.1 (Berkeley) 6/6/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: unix.c,v 1.23 2005/03/04 03:59:07 atatat Exp $");
|
||||
__RCSID("$NetBSD: unix.c,v 1.24 2005/09/04 18:59:57 elad Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -58,15 +58,85 @@ struct proc;
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <kvm.h>
|
||||
#include <err.h>
|
||||
#include "netstat.h"
|
||||
|
||||
static void unixdomainpr __P((struct socket *, caddr_t));
|
||||
static void unixdomainprhdr(void);
|
||||
static void unixdomainpr0(u_long, u_long, u_long, u_long, u_long, u_long,
|
||||
u_long, u_long, u_long, struct sockaddr_un *, int);
|
||||
static void unixdomainpr(struct socket *, caddr_t);
|
||||
|
||||
static struct file *file, *fileNFILE;
|
||||
static int nfiles;
|
||||
extern kvm_t *kvmd;
|
||||
|
||||
static void
|
||||
unixdomainprhdr(void)
|
||||
{
|
||||
printf("Active UNIX domain sockets\n");
|
||||
printf("%-8.8s %-6.6s %-6.6s %-6.6s %8.8s %8.8s %8.8s %8.8s Addr\n",
|
||||
"Address", "Type", "Recv-Q", "Send-Q", "Inode", "Conn", "Refs",
|
||||
"Nextref");
|
||||
}
|
||||
|
||||
static char *socktype[] =
|
||||
{ "#0", "stream", "dgram", "raw", "rdm", "seqpacket" };
|
||||
|
||||
static void
|
||||
unixdomainpr0(u_long so_pcb, u_long so_type, u_long rcvq, u_long sndq,
|
||||
u_long inode, u_long conn, u_long refs, u_long nextref,
|
||||
u_long addr, struct sockaddr_un *sun, int remote)
|
||||
{
|
||||
printf("%8lx %-6.6s %6ld %6ld %8lx %8lx %8lx %8lx",
|
||||
so_pcb, socktype[so_type], rcvq, sndq, inode, conn, refs,
|
||||
nextref);
|
||||
if (addr || remote)
|
||||
printf((remote ? " -> %.*s" : " %.*s"),
|
||||
(int)(sun->sun_len - (sizeof(*sun) - sizeof(sun->sun_path))),
|
||||
sun->sun_path);
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
static void
|
||||
unixdomainpr(so, soaddr)
|
||||
struct socket *so;
|
||||
caddr_t soaddr;
|
||||
{
|
||||
struct unpcb unp, runp;
|
||||
struct sockaddr_un sun, rsun;
|
||||
static int first = 1;
|
||||
int remote = 0;
|
||||
|
||||
if (kread((u_long)so->so_pcb, (char *)&unp, sizeof (unp)))
|
||||
return;
|
||||
if (unp.unp_addr)
|
||||
if (kread((u_long)unp.unp_addr, (char *)&sun, sizeof (sun)))
|
||||
unp.unp_addr = 0;
|
||||
|
||||
if (!unp.unp_addr) {
|
||||
memset(&rsun, 0, sizeof(rsun));
|
||||
if (unp.unp_conn &&
|
||||
kread((u_long)unp.unp_conn, (char *)&runp, sizeof (runp)) == 0 &&
|
||||
runp.unp_addr &&
|
||||
kread((u_long)runp.unp_addr, (char *)&rsun, sizeof (rsun)) == 0 &&
|
||||
rsun.sun_path[0] != '\0')
|
||||
remote = 1;
|
||||
}
|
||||
|
||||
if (first) {
|
||||
unixdomainprhdr();
|
||||
first = 0;
|
||||
}
|
||||
|
||||
unixdomainpr0((u_long)so->so_pcb, so->so_type, so->so_rcv.sb_cc,
|
||||
so->so_snd.sb_cc, (u_long)unp.unp_vnode,
|
||||
(u_long)unp.unp_conn, (u_long)unp.unp_refs,
|
||||
(u_long)unp.unp_nextref, (u_long)unp.unp_addr,
|
||||
remote ? &rsun : &sun, remote);
|
||||
}
|
||||
|
||||
void
|
||||
unixpr(off)
|
||||
u_long off;
|
||||
@ -76,65 +146,82 @@ unixpr(off)
|
||||
char *filebuf;
|
||||
struct protosw *unixsw = (struct protosw *)off;
|
||||
|
||||
filebuf = (char *)kvm_getfiles(kvmd, KERN_FILE, 0, &nfiles);
|
||||
if (filebuf == 0) {
|
||||
printf("file table read error: %s", kvm_geterr(kvmd));
|
||||
return;
|
||||
}
|
||||
file = (struct file *)(filebuf + sizeof(fp));
|
||||
fileNFILE = file + nfiles;
|
||||
for (fp = file; fp < fileNFILE; fp++) {
|
||||
if (fp->f_count == 0 || fp->f_type != DTYPE_SOCKET)
|
||||
continue;
|
||||
if (kread((u_long)fp->f_data, (char *)so, sizeof (*so)))
|
||||
continue;
|
||||
/* kludge */
|
||||
if (so->so_proto >= unixsw && so->so_proto <= unixsw + 2)
|
||||
if (so->so_pcb)
|
||||
unixdomainpr(so, fp->f_data);
|
||||
if (use_sysctl) {
|
||||
struct kinfo_pcb *pcblist;
|
||||
int mib[8];
|
||||
size_t namelen = 0, size = 0, i;
|
||||
char *mibname = "net.local.stream.pcblist";
|
||||
static int first = 1;
|
||||
int done = 0;
|
||||
|
||||
again:
|
||||
memset(mib, 0, sizeof(mib));
|
||||
|
||||
if (sysctlnametomib(mibname, mib,
|
||||
&namelen) == -1)
|
||||
err(1, "sysctlnametomib");
|
||||
|
||||
if (sysctl(mib, sizeof(mib) / sizeof(*mib), NULL, &size,
|
||||
NULL, 0) == -1)
|
||||
err(1, "sysctl (query)");
|
||||
|
||||
pcblist = malloc(size);
|
||||
memset(pcblist, 0, size);
|
||||
|
||||
mib[6] = sizeof(*pcblist);
|
||||
mib[7] = size / sizeof(*pcblist);
|
||||
|
||||
if (sysctl(mib, sizeof(mib) / sizeof(*mib), pcblist,
|
||||
&size, NULL, 0) == -1)
|
||||
err(1, "sysctl (copy)");
|
||||
|
||||
for (i = 0; i < size / sizeof(*pcblist); i++) {
|
||||
struct kinfo_pcb *ki = &pcblist[i];
|
||||
struct sockaddr_un *sun;
|
||||
int remote = 0;
|
||||
|
||||
if (first) {
|
||||
unixdomainprhdr();
|
||||
first = 0;
|
||||
}
|
||||
|
||||
sun = (struct sockaddr_un *)&ki->ki_dst;
|
||||
if (sun->sun_path[0] != '\0') {
|
||||
remote = 1;
|
||||
} else {
|
||||
sun = (struct sockaddr_un *)&ki->ki_src;
|
||||
}
|
||||
|
||||
unixdomainpr0(ki->ki_pcbaddr, ki->ki_type,
|
||||
ki->ki_rcvq, ki->ki_sndq,
|
||||
ki->ki_vnode, ki->ki_conn, ki->ki_refs,
|
||||
ki->ki_nextref, ki->ki_sockaddr, sun, remote);
|
||||
}
|
||||
|
||||
free(pcblist);
|
||||
|
||||
if (!done && mibname) {
|
||||
mibname = "net.local.dgram.pcblist";
|
||||
done = 1;
|
||||
goto again;
|
||||
}
|
||||
} else {
|
||||
filebuf = (char *)kvm_getfiles(kvmd, KERN_FILE, 0, &nfiles);
|
||||
if (filebuf == 0) {
|
||||
printf("file table read error: %s", kvm_geterr(kvmd));
|
||||
return;
|
||||
}
|
||||
file = (struct file *)(filebuf + sizeof(fp));
|
||||
fileNFILE = file + nfiles;
|
||||
for (fp = file; fp < fileNFILE; fp++) {
|
||||
if (fp->f_count == 0 || fp->f_type != DTYPE_SOCKET)
|
||||
continue;
|
||||
if (kread((u_long)fp->f_data, (char *)so, sizeof (*so)))
|
||||
continue;
|
||||
/* kludge */
|
||||
if (so->so_proto >= unixsw && so->so_proto <= unixsw + 2)
|
||||
if (so->so_pcb)
|
||||
unixdomainpr(so, fp->f_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *socktype[] =
|
||||
{ "#0", "stream", "dgram", "raw", "rdm", "seqpacket" };
|
||||
|
||||
static void
|
||||
unixdomainpr(so, soaddr)
|
||||
struct socket *so;
|
||||
caddr_t soaddr;
|
||||
{
|
||||
struct unpcb unp;
|
||||
struct sockaddr_un sun;
|
||||
static int first = 1;
|
||||
|
||||
if (kread((u_long)so->so_pcb, (char *)&unp, sizeof (unp)))
|
||||
return;
|
||||
if (unp.unp_addr)
|
||||
if (kread((u_long)unp.unp_addr, (char *)&sun, sizeof (sun)))
|
||||
unp.unp_addr = 0;
|
||||
if (first) {
|
||||
printf("Active UNIX domain sockets\n");
|
||||
printf(
|
||||
"%-8.8s %-6.6s %-6.6s %-6.6s %8.8s %8.8s %8.8s %8.8s Addr\n",
|
||||
"Address", "Type", "Recv-Q", "Send-Q",
|
||||
"Inode", "Conn", "Refs", "Nextref");
|
||||
first = 0;
|
||||
}
|
||||
printf("%8lx %-6.6s %6ld %6ld %8lx %8lx %8lx %8lx",
|
||||
(u_long) so->so_pcb, socktype[so->so_type], so->so_rcv.sb_cc, so->so_snd.sb_cc,
|
||||
(u_long) unp.unp_vnode, (u_long) unp.unp_conn,
|
||||
(u_long) unp.unp_refs, (u_long) unp.unp_nextref);
|
||||
if (unp.unp_addr)
|
||||
printf(" %.*s",
|
||||
(int) (sun.sun_len - (sizeof(sun) - sizeof(sun.sun_path))),
|
||||
sun.sun_path);
|
||||
else if (unp.unp_conn &&
|
||||
kread((u_long)unp.unp_conn, (char *)&unp, sizeof (unp)) == 0 &&
|
||||
unp.unp_addr &&
|
||||
kread((u_long)unp.unp_addr, (char *)&sun, sizeof (sun)) == 0 &&
|
||||
sun.sun_path[0] != '\0')
|
||||
printf(" -> %.*s",
|
||||
(int) (sun.sun_len - (sizeof(sun) - sizeof(sun.sun_path))),
|
||||
sun.sun_path);
|
||||
putchar('\n');
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user