2 * Copyright (c) 2002 Poul-Henning Kamp
3 * Copyright (c) 2002 Networks Associates Technology, Inc.
6 * This software was developed for the FreeBSD Project by Poul-Henning Kamp
7 * and NAI Labs, the Security Research Division of Network Associates, Inc.
8 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
9 * DARPA CHATS research program.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. The names of the authors may not be used to endorse or promote
20 * products derived from this software without specific prior written
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 #include <sys/disklabel.h>
48 #include <sys/kerneldump.h>
51 printheader(FILE *f, const struct kerneldumpheader *h, const char *devname, const char *md5)
55 fprintf(f, "Good dump found on device %s\n", devname);
56 fprintf(f, " Architecture: %s\n", h->architecture);
57 fprintf(f, " Architecture version: %d\n", h->architectureversion);
58 fprintf(f, " Dump length: %lldB (%lld MB)\n",
59 h->dumplength, h->dumplength / (1024 * 1024));
60 fprintf(f, " Blocksize: %d\n", h->blocksize);
62 fprintf(f, " Dumptime: %s", ctime(&t));
63 fprintf(f, " Hostname: %s\n", h->hostname);
64 fprintf(f, " Versionstring: %s", h->versionstring);
65 fprintf(f, " Panicstring: %s\n", h->panicstring);
66 fprintf(f, " MD5: %s\n", md5);
71 DoFile(const char *devname)
73 int fd, fdcore, fdinfo, error, wl;
74 off_t mediasize, dumpsize, firsthd, lasthd;
76 struct kerneldumpheader kdhf, kdhl;
82 fd = open(devname, O_RDONLY);
87 error = ioctl(fd, DIOCGMEDIASIZE, &mediasize);
89 error = ioctl(fd, DIOCGSECTORSIZE, §orsize);
91 warn("Couldn't find media and/or sector size of %s)", devname);
94 printf("Mediasize = %lld\n", mediasize);
95 printf("Sectorsize = %u\n", sectorsize);
96 lasthd = mediasize - sectorsize;
97 lseek(fd, lasthd, SEEK_SET);
98 error = read(fd, &kdhl, sizeof kdhl);
99 if (error != sizeof kdhl) {
100 warn("Error Reading last dump header at offset %lld in %s",
104 if (kerneldump_parity(&kdhl)) {
105 warnx("Parity error on last dump header on %s\n", devname);
108 if (memcmp(kdhl.magic, KERNELDUMPMAGIC, sizeof kdhl.magic)) {
109 warnx("Magic mismatch on last dump header on %s\n", devname);
112 if (kdhl.version != KERNELDUMPVERSION) {
113 warnx("Unknown version (%d) in last dump header on %s\n",
114 kdhl.version, devname);
117 firsthd = lasthd - kdhl.dumplength - sizeof kdhf;
118 lseek(fd, firsthd, SEEK_SET);
119 error = read(fd, &kdhf, sizeof kdhf);
120 if (error != sizeof kdhf) {
121 warn("Error Reading first dump header at offset %lld in %s",
125 if (memcmp(&kdhl, &kdhf, sizeof kdhl)) {
126 warn("First and last dump headers disagree on %s\n", devname);
129 md5 = MD5Data((unsigned char *)&kdhl, sizeof kdhl, NULL);
130 sprintf(buf, "%s.info", md5);
131 fdinfo = open(buf, O_WRONLY | O_CREAT | O_EXCL, 0600);
132 if (fdinfo < 0 && errno == EEXIST) {
133 printf("Dump on device %s already saved\n", devname);
140 sprintf(buf, "%s.core", md5);
141 fdcore = open(buf, O_WRONLY | O_CREAT | O_EXCL, 0600);
146 info = fdopen(fdinfo, "w");
147 printheader(stdout, &kdhl, devname, md5);
148 printheader(info, &kdhl, devname, md5);
149 dumpsize = kdhl.dumplength;
150 printf("Saving dump to file...\n");
151 while (dumpsize > 0) {
155 error = read(fd, buf, wl);
157 warn("read error on %s\n", devname);
160 error = write(fdcore, buf, wl);
162 warn("write error on %s.core file\n", md5);
169 printf("Dump saved\n");
175 errx(1, "usage: ...");
180 main(int argc, char **argv)
185 while ((ch = getopt(argc, argv, "cdfkN:vz")) != -1)
201 error = chdir(argv[0]);
203 err(1, "chdir(%s)", argv[0]);
212 if (strcmp(fsp->fs_vfstype, "swap") &&
213 strcmp(fsp->fs_vfstype, "dump"))
215 DoFile(fsp->fs_spec);
218 for (i = 0; i < argc; i++)