Home | History | Annotate | Line # | Download | only in shmif_dumpbus
shmif_dumpbus.c revision 1.11.4.1
      1  1.11.4.1  msaitoh /*	$NetBSD: shmif_dumpbus.c,v 1.11.4.1 2014/12/22 01:59:14 msaitoh Exp $	*/
      2       1.1    pooka 
      3       1.1    pooka /*-
      4       1.1    pooka  * Copyright (c) 2010 Antti Kantee.  All Rights Reserved.
      5       1.1    pooka  *
      6       1.1    pooka  * Redistribution and use in source and binary forms, with or without
      7       1.1    pooka  * modification, are permitted provided that the following conditions
      8       1.1    pooka  * are met:
      9       1.1    pooka  * 1. Redistributions of source code must retain the above copyright
     10       1.1    pooka  *    notice, this list of conditions and the following disclaimer.
     11       1.1    pooka  * 2. Redistributions in binary form must reproduce the above copyright
     12       1.1    pooka  *    notice, this list of conditions and the following disclaimer in the
     13       1.1    pooka  *    documentation and/or other materials provided with the distribution.
     14       1.1    pooka  *
     15       1.1    pooka  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     16       1.1    pooka  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     17       1.1    pooka  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18       1.1    pooka  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     19       1.1    pooka  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     20       1.1    pooka  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     21       1.1    pooka  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22       1.1    pooka  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     23       1.1    pooka  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     24       1.1    pooka  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     25       1.1    pooka  * SUCH DAMAGE.
     26       1.1    pooka  */
     27       1.1    pooka 
     28       1.1    pooka /*
     29       1.1    pooka  * Convert shmif bus traffic to a pcap file which can be then
     30       1.1    pooka  * examined with tcpdump -r, wireshark, etc.
     31       1.1    pooka  */
     32       1.1    pooka 
     33      1.11    pooka #include <rump/rumpuser_port.h>
     34      1.11    pooka 
     35      1.10    pooka #ifndef lint
     36  1.11.4.1  msaitoh __RCSID("$NetBSD: shmif_dumpbus.c,v 1.11.4.1 2014/12/22 01:59:14 msaitoh Exp $");
     37      1.10    pooka #endif /* !lint */
     38      1.10    pooka 
     39       1.1    pooka #include <sys/types.h>
     40       1.1    pooka #include <sys/mman.h>
     41       1.1    pooka #include <sys/stat.h>
     42      1.11    pooka #ifdef __NetBSD__
     43      1.11    pooka #include <sys/bswap.h>
     44      1.11    pooka #endif
     45       1.5    pooka 
     46       1.1    pooka #include <assert.h>
     47       1.1    pooka #include <err.h>
     48       1.1    pooka #include <fcntl.h>
     49       1.1    pooka #include <inttypes.h>
     50       1.1    pooka #include <pcap.h>
     51       1.1    pooka #include <stdbool.h>
     52       1.1    pooka #include <stdio.h>
     53       1.1    pooka #include <stdlib.h>
     54       1.1    pooka #include <string.h>
     55       1.1    pooka #include <unistd.h>
     56       1.1    pooka 
     57       1.1    pooka #include "shmifvar.h"
     58       1.1    pooka 
     59       1.8    joerg __dead static void
     60       1.1    pooka usage(void)
     61       1.1    pooka {
     62       1.1    pooka 
     63      1.11    pooka #ifndef PLATFORM_HAS_SETGETPROGNAME
     64      1.11    pooka #define getprogname() "shmif_dumpbus"
     65      1.11    pooka #endif
     66      1.11    pooka 
     67       1.1    pooka 	fprintf(stderr, "usage: %s [-h] [-p pcapfile] buspath\n",getprogname());
     68       1.1    pooka 	exit(1);
     69       1.1    pooka }
     70       1.1    pooka 
     71       1.1    pooka #define BUFSIZE 64*1024
     72  1.11.4.1  msaitoh 
     73  1.11.4.1  msaitoh /*
     74  1.11.4.1  msaitoh  * byte swapdom
     75  1.11.4.1  msaitoh  */
     76  1.11.4.1  msaitoh static uint32_t
     77  1.11.4.1  msaitoh swp32(uint32_t x)
     78  1.11.4.1  msaitoh {
     79  1.11.4.1  msaitoh 	uint32_t v;
     80  1.11.4.1  msaitoh 
     81  1.11.4.1  msaitoh 	v = (((x) & 0xff000000) >> 24) |
     82  1.11.4.1  msaitoh 	    (((x) & 0x00ff0000) >>  8) |
     83  1.11.4.1  msaitoh 	    (((x) & 0x0000ff00) <<  8) |
     84  1.11.4.1  msaitoh 	    (((x) & 0x000000ff) << 24);
     85  1.11.4.1  msaitoh 	return v;
     86  1.11.4.1  msaitoh }
     87  1.11.4.1  msaitoh 
     88  1.11.4.1  msaitoh static uint64_t
     89  1.11.4.1  msaitoh swp64(uint64_t x)
     90  1.11.4.1  msaitoh {
     91  1.11.4.1  msaitoh 	uint64_t v;
     92  1.11.4.1  msaitoh 
     93  1.11.4.1  msaitoh 	v = (((x) & 0xff00000000000000ull) >> 56) |
     94  1.11.4.1  msaitoh 	    (((x) & 0x00ff000000000000ull) >> 40) |
     95  1.11.4.1  msaitoh 	    (((x) & 0x0000ff0000000000ull) >> 24) |
     96  1.11.4.1  msaitoh 	    (((x) & 0x000000ff00000000ull) >>  8) |
     97  1.11.4.1  msaitoh 	    (((x) & 0x00000000ff000000ull) <<  8) |
     98  1.11.4.1  msaitoh 	    (((x) & 0x0000000000ff0000ull) << 24) |
     99  1.11.4.1  msaitoh 	    (((x) & 0x000000000000ff00ull) << 40) |
    100  1.11.4.1  msaitoh 	    (((x) & 0x00000000000000ffull) << 56);
    101  1.11.4.1  msaitoh 	return v;
    102  1.11.4.1  msaitoh }
    103  1.11.4.1  msaitoh 
    104  1.11.4.1  msaitoh #define FIXENDIAN32(x) (doswap ? swp32(x) : (x))
    105  1.11.4.1  msaitoh #define FIXENDIAN64(x) (doswap ? swp64(x) : (x))
    106  1.11.4.1  msaitoh 
    107  1.11.4.1  msaitoh /* compat for bus version 2 */
    108  1.11.4.1  msaitoh struct shmif_pkthdr2 {
    109  1.11.4.1  msaitoh 	uint32_t sp_len;
    110  1.11.4.1  msaitoh 
    111  1.11.4.1  msaitoh 	uint32_t sp_sec;
    112  1.11.4.1  msaitoh 	uint32_t sp_usec;
    113  1.11.4.1  msaitoh };
    114  1.11.4.1  msaitoh 
    115       1.1    pooka int
    116       1.1    pooka main(int argc, char *argv[])
    117       1.1    pooka {
    118       1.1    pooka 	struct stat sb;
    119       1.1    pooka 	void *busmem;
    120       1.1    pooka 	const char *pcapfile = NULL;
    121       1.1    pooka 	uint32_t curbus, buslast;
    122       1.1    pooka 	struct shmif_mem *bmem;
    123       1.5    pooka 	int fd, i, ch;
    124       1.1    pooka 	int bonus;
    125       1.1    pooka 	char *buf;
    126       1.9    pooka 	bool hflag = false, doswap = false;
    127       1.5    pooka 	pcap_dumper_t *pdump;
    128       1.9    pooka 	FILE *dumploc = stdout;
    129  1.11.4.1  msaitoh 	int useversion;
    130       1.1    pooka 
    131      1.11    pooka #ifdef PLATFORM_HAS_SETGETPROGNAME
    132       1.1    pooka 	setprogname(argv[0]);
    133      1.11    pooka #endif
    134      1.11    pooka 
    135       1.1    pooka 	while ((ch = getopt(argc, argv, "hp:")) != -1) {
    136       1.1    pooka 		switch (ch) {
    137       1.1    pooka 		case 'h':
    138       1.1    pooka 			hflag = true;
    139       1.1    pooka 			break;
    140       1.1    pooka 		case 'p':
    141       1.1    pooka 			pcapfile = optarg;
    142       1.1    pooka 			break;
    143       1.1    pooka 		default:
    144       1.1    pooka 			usage();
    145       1.1    pooka 		}
    146       1.1    pooka 	}
    147       1.1    pooka 
    148       1.1    pooka 	argc -= optind;
    149       1.1    pooka 	argv += optind;
    150       1.1    pooka 
    151       1.1    pooka 	if (argc != 1)
    152       1.1    pooka 		usage();
    153       1.1    pooka 
    154       1.1    pooka 	buf = malloc(BUFSIZE);
    155       1.1    pooka 	if (buf == NULL)
    156       1.1    pooka 		err(1, "malloc");
    157       1.1    pooka 
    158       1.1    pooka 	fd = open(argv[0], O_RDONLY);
    159       1.1    pooka 	if (fd == -1)
    160       1.1    pooka 		err(1, "open bus");
    161       1.1    pooka 
    162       1.1    pooka 	if (fstat(fd, &sb) == -1)
    163       1.1    pooka 		err(1, "stat");
    164       1.1    pooka 
    165       1.1    pooka 	busmem = mmap(NULL, sb.st_size, PROT_READ, MAP_FILE|MAP_SHARED, fd, 0);
    166       1.1    pooka 	if (busmem == MAP_FAILED)
    167       1.1    pooka 		err(1, "mmap");
    168       1.1    pooka 	bmem = busmem;
    169       1.1    pooka 
    170       1.5    pooka 	if (bmem->shm_magic != SHMIF_MAGIC) {
    171  1.11.4.1  msaitoh 		if (bmem->shm_magic != swp32(SHMIF_MAGIC))
    172       1.5    pooka 			errx(1, "%s not a shmif bus", argv[0]);
    173  1.11.4.1  msaitoh 		doswap = true;
    174  1.11.4.1  msaitoh 	}
    175  1.11.4.1  msaitoh 	if (FIXENDIAN32(bmem->shm_version) != SHMIF_VERSION) {
    176  1.11.4.1  msaitoh 		if (FIXENDIAN32(bmem->shm_version) != 2) {
    177  1.11.4.1  msaitoh 			errx(1, "bus version %d, program %d",
    178  1.11.4.1  msaitoh 			    FIXENDIAN32(bmem->shm_version), SHMIF_VERSION);
    179  1.11.4.1  msaitoh 		}
    180  1.11.4.1  msaitoh 		useversion = 2;
    181  1.11.4.1  msaitoh 	} else {
    182  1.11.4.1  msaitoh 		useversion = 3;
    183       1.5    pooka 	}
    184       1.9    pooka 
    185       1.9    pooka 	if (pcapfile && strcmp(pcapfile, "-") == 0)
    186       1.9    pooka 		dumploc = stderr;
    187       1.9    pooka 
    188       1.9    pooka 	fprintf(dumploc, "bus version %d, lock: %d, generation: %" PRIu64
    189       1.1    pooka 	    ", firstoff: 0x%04x, lastoff: 0x%04x\n",
    190  1.11.4.1  msaitoh 	    FIXENDIAN32(bmem->shm_version), FIXENDIAN32(bmem->shm_lock),
    191  1.11.4.1  msaitoh 	    FIXENDIAN64(bmem->shm_gen),
    192  1.11.4.1  msaitoh 	    FIXENDIAN32(bmem->shm_first), FIXENDIAN32(bmem->shm_last));
    193       1.1    pooka 
    194       1.1    pooka 	if (hflag)
    195       1.1    pooka 		exit(0);
    196       1.1    pooka 
    197       1.1    pooka 	if (pcapfile) {
    198       1.5    pooka 		pcap_t *pcap = pcap_open_dead(DLT_EN10MB, 1518);
    199       1.5    pooka 		pdump = pcap_dump_open(pcap, pcapfile);
    200       1.5    pooka 		if (pdump == NULL)
    201       1.5    pooka 			err(1, "cannot open pcap dump file");
    202       1.1    pooka 	} else {
    203       1.5    pooka 		/* XXXgcc */
    204       1.5    pooka 		pdump = NULL;
    205       1.1    pooka 	}
    206       1.7    pooka 
    207  1.11.4.1  msaitoh 	curbus = FIXENDIAN32(bmem->shm_first);
    208  1.11.4.1  msaitoh 	buslast = FIXENDIAN32(bmem->shm_last);
    209       1.1    pooka 	if (curbus == BUSMEM_DATASIZE)
    210       1.1    pooka 		curbus = 0;
    211       1.1    pooka 
    212       1.1    pooka 	bonus = 0;
    213       1.1    pooka 	if (buslast < curbus)
    214       1.1    pooka 		bonus = 1;
    215       1.1    pooka 
    216       1.1    pooka 	i = 0;
    217  1.11.4.1  msaitoh 
    218       1.1    pooka 	while (curbus <= buslast || bonus) {
    219       1.5    pooka 		struct pcap_pkthdr packhdr;
    220       1.1    pooka 		uint32_t oldoff;
    221       1.5    pooka 		uint32_t curlen;
    222  1.11.4.1  msaitoh 		uint32_t sp_sec, sp_usec, sp_len;
    223       1.1    pooka 		bool wrap;
    224       1.1    pooka 
    225       1.3    pooka 		assert(curbus < sb.st_size);
    226       1.3    pooka 
    227       1.1    pooka 		wrap = false;
    228       1.1    pooka 		oldoff = curbus;
    229  1.11.4.1  msaitoh 
    230  1.11.4.1  msaitoh 		if (useversion == 3) {
    231  1.11.4.1  msaitoh 			struct shmif_pkthdr sp;
    232  1.11.4.1  msaitoh 
    233  1.11.4.1  msaitoh 			curbus = shmif_busread(bmem,
    234  1.11.4.1  msaitoh 			    &sp, oldoff, sizeof(sp), &wrap);
    235  1.11.4.1  msaitoh 			sp_len = FIXENDIAN32(sp.sp_len);
    236  1.11.4.1  msaitoh 			sp_sec = FIXENDIAN32(sp.sp_sec);
    237  1.11.4.1  msaitoh 			sp_usec = FIXENDIAN32(sp.sp_usec);
    238  1.11.4.1  msaitoh 		} else {
    239  1.11.4.1  msaitoh 			struct shmif_pkthdr2 sp2;
    240  1.11.4.1  msaitoh 
    241  1.11.4.1  msaitoh 			curbus = shmif_busread(bmem,
    242  1.11.4.1  msaitoh 			    &sp2, oldoff, sizeof(sp2), &wrap);
    243  1.11.4.1  msaitoh 			sp_len = FIXENDIAN32(sp2.sp_len);
    244  1.11.4.1  msaitoh 			sp_sec = FIXENDIAN32(sp2.sp_sec);
    245  1.11.4.1  msaitoh 			sp_usec = FIXENDIAN32(sp2.sp_usec);
    246  1.11.4.1  msaitoh 		}
    247       1.1    pooka 		if (wrap)
    248       1.1    pooka 			bonus = 0;
    249       1.1    pooka 
    250       1.3    pooka 		assert(curbus < sb.st_size);
    251  1.11.4.1  msaitoh 		curlen = sp_len;
    252       1.3    pooka 
    253       1.5    pooka 		if (curlen == 0) {
    254       1.1    pooka 			continue;
    255       1.3    pooka 		}
    256       1.1    pooka 
    257       1.9    pooka 		fprintf(dumploc, "packet %d, offset 0x%04x, length 0x%04x, "
    258  1.11.4.1  msaitoh 			    "ts %d/%06d\n", i++, curbus, curlen,
    259  1.11.4.1  msaitoh 			    sp_sec, sp_usec);
    260       1.1    pooka 
    261       1.3    pooka 		if (!pcapfile) {
    262       1.1    pooka 			curbus = shmif_busread(bmem,
    263       1.5    pooka 			    buf, curbus, curlen, &wrap);
    264       1.1    pooka 			if (wrap)
    265       1.1    pooka 				bonus = 0;
    266       1.1    pooka 			continue;
    267       1.1    pooka 		}
    268       1.1    pooka 
    269       1.1    pooka 		memset(&packhdr, 0, sizeof(packhdr));
    270       1.5    pooka 		packhdr.caplen = packhdr.len = curlen;
    271  1.11.4.1  msaitoh 		packhdr.ts.tv_sec = sp_sec;
    272  1.11.4.1  msaitoh 		packhdr.ts.tv_usec = sp_usec;
    273       1.5    pooka 		assert(curlen <= BUFSIZE);
    274       1.5    pooka 
    275       1.5    pooka 		curbus = shmif_busread(bmem, buf, curbus, curlen, &wrap);
    276       1.5    pooka 		pcap_dump((u_char *)pdump, &packhdr, (u_char *)buf);
    277       1.1    pooka 		if (wrap)
    278       1.1    pooka 			bonus = 0;
    279       1.1    pooka 	}
    280       1.1    pooka 
    281       1.5    pooka 	if (pcapfile)
    282       1.5    pooka 		pcap_dump_close(pdump);
    283       1.5    pooka 
    284       1.1    pooka 	return 0;
    285       1.1    pooka }
    286