Index: kvm_vnet.c
===================================================================
--- kvm_vnet.c	(revision 0)
+++ kvm_vnet.c	(revision 0)
@@ -0,0 +1,139 @@
+/*-
+ * Copyright (c) 2009 Robert N. M. Watson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+
+#define	_WANT_PRISON
+#define _WANT_UCRED
+
+#include <sys/_lock.h>
+#include <sys/_mutex.h>
+#include <sys/_task.h>
+#include <sys/jail.h>
+#include <sys/proc.h>
+#include <sys/vimage.h>
+
+#include <nlist.h>
+#include <kvm.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#include "kvm_private.h"
+
+#ifndef VIMAGE_H_READY_FOR_REALITY
+struct vnet {
+        LIST_ENTRY(vnet)         vnet_le;       /* all vnets list */
+        u_int                    vnet_magic_n;
+        u_int                    ifcnt;
+        u_int                    sockcnt;
+        void                    *vnet_data_mem;
+        uintptr_t                vnet_data_base;
+};
+LIST_HEAD(vnet_list_head, vnet);
+#endif
+
+/*
+ * Set up libkvm to handle virtual network stack symbols by selecting a
+ * starting pid.
+ */
+int
+kvm_vnet_selectpid(kvm_t *kd, pid_t pid)
+{
+	struct proc proc;
+	struct ucred cred;
+	struct prison prison;
+	struct vnet vnet;
+	struct nlist nl[] = {
+#define	NLIST_START_VNET	0
+		{ .n_name = "__start_set_vnet" },
+#define	NLIST_STOP_VNET		1
+		{ .n_name = "__stop_set_vnet" },
+#define	NLIST_VNET_HEAD		2
+		{ .n_name = "vnet_head" },
+#define	NLIST_ALLPROC		3
+		{ .n_name = "allproc" },
+		{ .n_name = NULL },
+	};
+	uintptr_t procp;
+
+	/*
+	 * Locate and cache locations of important symbols.
+	 */
+	if (kvm_nlist(kd, nl) != 0) {
+		_kvm_err(kd, kd->program, "kvm_vnet_selectpid: no namelist");
+		return (-1);
+	}
+
+	/*
+	 * First, find the process for this pid.
+	 */
+	procp = nl[NLIST_ALLPROC].n_value;
+	while (procp != 0) {
+		if (kvm_read(kd, procp, &proc, sizeof(proc)) != sizeof(proc)) {
+			_kvm_err(kd, kd->program, "kvm_vnet_selectpid: proc");
+			return (-1);
+		}
+		if (proc.p_pid == pid)
+			break;
+		procp = (uintptr_t)LIST_NEXT(&proc, p_list);
+	}
+	if (procp == 0) {
+		_kvm_err(kd, kd->program, "kvm_vnet_selectpid: pid not found");
+		return (-1);
+	}
+	if (kvm_read(kd, (uintptr_t)proc.p_ucred, &cred, sizeof(cred)) !=
+	    sizeof(cred)) {
+		_kvm_err(kd, kd->program, "kvm_vnet_selectpid: cred");
+		return (-1);
+	}
+	if (cred.cr_prison == NULL) {
+		_kvm_err(kd, kd->program, "kvm_vnet_selectpid: no jail");
+		return (-1);
+	}
+	if (kvm_read(kd, (uintptr_t)cred.cr_prison, &prison, sizeof(prison)) !=
+	    sizeof(prison)) {
+		_kvm_err(kd, kd->program, "kvm_vnet_selectpid: prison");
+		return (-1);
+	}
+	if (prison.pr_vnet == NULL) {
+		_kvm_err(kd, kd->program, "kvm_vnet_selectpid: no vnet");
+		return (-1);
+	}
+	if (kvm_read(kd, (uintptr_t)prison.pr_vnet, &vnet, sizeof(vnet)) !=
+	    sizeof(vnet)) {
+		_kvm_err(kd, kd->program, "kvm_vnet_selectpid: vnet");
+		return (-1);
+	}
+	kd->vnet_initialized = 1;
+	kd->vnet_start = nl[NLIST_START_VNET].n_value;
+	kd->vnet_stop = nl[NLIST_STOP_VNET].n_value;
+	kd->vnet_current = (uintptr_t)prison.pr_vnet;
+	kd->vnet_base = (uintptr_t)vnet.vnet_data_mem - kd->vnet_start;
+	return (0);
+}

Property changes on: kvm_vnet.c
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + FreeBSD=%H
Added: svn:eol-style
   + native

Index: kvm_private.h
===================================================================
--- kvm_private.h	(revision 195741)
+++ kvm_private.h	(working copy)
@@ -62,6 +62,12 @@
 	 */
 	struct vmstate *vmst;
 	int	rawdump;	/* raw dump format */
+
+	int		vnet_initialized;	/* vnet fields set up */
+	uintptr_t	vnet_start;	/* start of kernel's vnet region */
+	uintptr_t	vnet_stop;	/* stop of kernel's vnet region */
+	uintptr_t	vnet_current;	/* vnet we're working with */
+	uintptr_t	vnet_base;	/* vnet base of current vnet */
 };
 
 /*
Index: Makefile
===================================================================
--- Makefile	(revision 195741)
+++ Makefile	(working copy)
@@ -10,7 +10,7 @@
 .endif
 
 SRCS=	kvm.c kvm_${MACHINE_ARCH}.c kvm_cptime.c kvm_file.c kvm_getloadavg.c \
-	kvm_getswapinfo.c kvm_pcpu.c kvm_proc.c
+	kvm_getswapinfo.c kvm_pcpu.c kvm_proc.c kvm_vnet.c
 .if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "arm"
 SRCS+=	kvm_minidump_${MACHINE_ARCH}.c
 .endif
