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 +__FBSDID("$FreeBSD$"); + +#include + +#define _WANT_PRISON +#define _WANT_UCRED + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#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