⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 savefile.c

📁 用来监视网络通信数据的源代码和应用程序,方便网络程序底层开发.
💻 C
📖 第 1 页 / 共 3 页
字号:
	 * These DLT_* codes have different values on different
	 * platforms; we map them to LINKTYPE_* codes that
	 * have values that should never be equal to any DLT_*
	 * code.
	 */
#ifdef DLT_FR
	/* BSD/OS Frame Relay */
	{ DLT_FR,		LINKTYPE_FRELAY },
#endif

	{ DLT_SYMANTEC_FIREWALL, LINKTYPE_SYMANTEC_FIREWALL },
	{ DLT_ATM_RFC1483, 	LINKTYPE_ATM_RFC1483 },
	{ DLT_RAW,		LINKTYPE_RAW },
	{ DLT_SLIP_BSDOS,	LINKTYPE_SLIP_BSDOS },
	{ DLT_PPP_BSDOS,	LINKTYPE_PPP_BSDOS },

	/* BSD/OS Cisco HDLC */
	{ DLT_C_HDLC,		LINKTYPE_C_HDLC },

	/*
	 * These DLT_* codes are not on all platforms, but, so far,
	 * there don't appear to be any platforms that define
	 * other codes with those values; we map them to
	 * different LINKTYPE_* values anyway, just in case.
	 */

	/* Linux ATM Classical IP */
	{ DLT_ATM_CLIP,		LINKTYPE_ATM_CLIP },

	/* NetBSD sync/async serial PPP (or Cisco HDLC) */
	{ DLT_PPP_SERIAL,	LINKTYPE_PPP_HDLC },

	/* NetBSD PPP over Ethernet */
	{ DLT_PPP_ETHER,	LINKTYPE_PPP_ETHER },

	/* IEEE 802.11 wireless */
	{ DLT_IEEE802_11,	LINKTYPE_IEEE802_11 },

	/* Frame Relay */
	{ DLT_FRELAY,		LINKTYPE_FRELAY },

	/* OpenBSD loopback */
	{ DLT_LOOP,		LINKTYPE_LOOP },

	/* Linux cooked socket capture */
	{ DLT_LINUX_SLL,	LINKTYPE_LINUX_SLL },

	/* Apple LocalTalk hardware */
	{ DLT_LTALK,		LINKTYPE_LTALK },

	/* Acorn Econet */
	{ DLT_ECONET,		LINKTYPE_ECONET },

	/* OpenBSD DLT_PFLOG */
	{ DLT_PFLOG,		LINKTYPE_PFLOG },

	/* For Cisco-internal use */
	{ DLT_CISCO_IOS,	LINKTYPE_CISCO_IOS },

	/* Prism II monitor-mode header plus 802.11 header */
	{ DLT_PRISM_HEADER,	LINKTYPE_PRISM_HEADER },

	/* FreeBSD Aironet driver stuff */
	{ DLT_AIRONET_HEADER,	LINKTYPE_AIRONET_HEADER },

	/* Siemens HiPath HDLC */
	{ DLT_HHDLC,		LINKTYPE_HHDLC },

	/* RFC 2625 IP-over-Fibre Channel */
	{ DLT_IP_OVER_FC,	LINKTYPE_IP_OVER_FC },

	/* Solaris+SunATM */
	{ DLT_SUNATM,		LINKTYPE_SUNATM },

	/* RapidIO */
	{ DLT_RIO,		LINKTYPE_RIO },

	/* PCI Express */
	{ DLT_PCI_EXP,		LINKTYPE_PCI_EXP },

	/* Xilinx Aurora link layer */
	{ DLT_AURORA,		LINKTYPE_AURORA },

	/* 802.11 plus BSD radio header */
	{ DLT_IEEE802_11_RADIO,	LINKTYPE_IEEE802_11_RADIO },

	/* Tazmen Sniffer Protocol */
	{ DLT_TZSP,		LINKTYPE_TZSP },

	/* Arcnet with Linux-style link-layer headers */
	{ DLT_ARCNET_LINUX,	LINKTYPE_ARCNET_LINUX },

        /* Juniper-internal chassis encapsulation */
        { DLT_JUNIPER_MLPPP,    LINKTYPE_JUNIPER_MLPPP },
        { DLT_JUNIPER_MLFR,     LINKTYPE_JUNIPER_MLFR },
        { DLT_JUNIPER_ES,       LINKTYPE_JUNIPER_ES },
        { DLT_JUNIPER_GGSN,     LINKTYPE_JUNIPER_GGSN },
        { DLT_JUNIPER_MFR,      LINKTYPE_JUNIPER_MFR },
        { DLT_JUNIPER_ATM2,     LINKTYPE_JUNIPER_ATM2 },
        { DLT_JUNIPER_SERVICES, LINKTYPE_JUNIPER_SERVICES },
        { DLT_JUNIPER_ATM1,     LINKTYPE_JUNIPER_ATM1 },

	/* Apple IP-over-IEEE 1394 cooked header */
	{ DLT_APPLE_IP_OVER_IEEE1394, LINKTYPE_APPLE_IP_OVER_IEEE1394 },

	/* DOCSIS MAC frames */
	{ DLT_DOCSIS,		LINKTYPE_DOCSIS },

	/* IrDA IrLAP packets + Linux-cooked header */
	{ DLT_LINUX_IRDA,	LINKTYPE_LINUX_IRDA },

	/* IBM SP and Next Federation switches */
	{ DLT_IBM_SP,		LINKTYPE_IBM_SP },
	{ DLT_IBM_SN,		LINKTYPE_IBM_SN },

	/* 802.11 plus AVS radio header */
	{ DLT_IEEE802_11_RADIO_AVS, LINKTYPE_IEEE802_11_RADIO_AVS },

	/*
	 * Any platform that defines additional DLT_* codes should:
	 *
	 *	request a LINKTYPE_* code and value from tcpdump.org,
	 *	as per the above;
	 *
	 *	add, in their version of libpcap, an entry to map
	 *	those DLT_* codes to the corresponding LINKTYPE_*
	 *	code;
	 *
	 *	redefine, in their "net/bpf.h", any DLT_* values
	 *	that collide with the values used by their additional
	 *	DLT_* codes, to remove those collisions (but without
	 *	making them collide with any of the LINKTYPE_*
	 *	values equal to 50 or above; they should also avoid
	 *	defining DLT_* values that collide with those
	 *	LINKTYPE_* values, either).
	 */

	/* Juniper-internal chassis encapsulation */
	{ DLT_JUNIPER_MONITOR,	LINKTYPE_JUNIPER_MONITOR },

	{ -1,			-1 }
};

static int
dlt_to_linktype(int dlt)
{
	int i;

	for (i = 0; map[i].dlt != -1; i++) {
		if (map[i].dlt == dlt)
			return (map[i].linktype);
	}

	/*
	 * If we don't have a mapping for this DLT_ code, return an
	 * error; that means that the table above needs to have an
	 * entry added.
	 */
	return (-1);
}

static int
linktype_to_dlt(int linktype)
{
	int i;

	for (i = 0; map[i].linktype != -1; i++) {
		if (map[i].linktype == linktype)
			return (map[i].dlt);
	}

	/*
	 * If we don't have an entry for this link type, return
	 * the link type value; it may be a DLT_ value from an
	 * older version of libpcap.
	 */
	return linktype;
}

static int
sf_write_header(FILE *fp, int linktype, int thiszone, int snaplen)
{
	struct pcap_file_header hdr;

	hdr.magic = TCPDUMP_MAGIC;
	hdr.version_major = PCAP_VERSION_MAJOR;
	hdr.version_minor = PCAP_VERSION_MINOR;

	hdr.thiszone = thiszone;
	hdr.snaplen = snaplen;
	hdr.sigfigs = 0;
	hdr.linktype = linktype;

	if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1)
		return (-1);

	return (0);
}

static void
swap_hdr(struct pcap_file_header *hp)
{
	hp->version_major = SWAPSHORT(hp->version_major);
	hp->version_minor = SWAPSHORT(hp->version_minor);
	hp->thiszone = SWAPLONG(hp->thiszone);
	hp->sigfigs = SWAPLONG(hp->sigfigs);
	hp->snaplen = SWAPLONG(hp->snaplen);
	hp->linktype = SWAPLONG(hp->linktype);
}

static int
sf_getnonblock(pcap_t *p, char *errbuf)
{
	/*
	 * This is a savefile, not a live capture file, so never say
	 * it's in non-blocking mode.
	 */
	return (0);
}

static int
sf_setnonblock(pcap_t *p, int nonblock, char *errbuf)
{
	/*
	 * This is a savefile, not a live capture file, so ignore
	 * requests to put it in non-blocking mode.
	 */
	return (0);
}

static int
sf_stats(pcap_t *p, struct pcap_stat *ps)
{
	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
	    "Statistics aren't available from savefiles");
	return (-1);
}

static void
sf_close(pcap_t *p)
{
	if (p->sf.rfile != stdin)
		(void)fclose(p->sf.rfile);
	if (p->sf.base != NULL)
		free(p->sf.base);
}

pcap_t *
pcap_open_offline(const char *fname, char *errbuf)
{
	register pcap_t *p;
	register FILE *fp;
	struct pcap_file_header hdr;
	bpf_u_int32 magic;
	int linklen;

	p = (pcap_t *)malloc(sizeof(*p));
	if (p == NULL) {
		strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE);
		return (NULL);
	}

	memset((char *)p, 0, sizeof(*p));

	if (fname[0] == '-' && fname[1] == '\0')
		fp = stdin;
	else {
#ifndef WIN32
		fp = fopen(fname, "r");
#else
		fp = fopen(fname, "rb");
#endif
		if (fp == NULL) {
			snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname,
			    pcap_strerror(errno));
			goto bad;
		}
	}
	if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1) {
		snprintf(errbuf, PCAP_ERRBUF_SIZE, "fread: %s",
		    pcap_strerror(errno));
		goto bad;
	}
	magic = hdr.magic;
	if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC) {
		magic = SWAPLONG(magic);
		if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC) {
			snprintf(errbuf, PCAP_ERRBUF_SIZE,
			    "bad dump file format");
			goto bad;
		}
		p->sf.swapped = 1;
		swap_hdr(&hdr);
	}
	if (magic == KUZNETZOV_TCPDUMP_MAGIC) {
		/*
		 * XXX - the patch that's in some versions of libpcap
		 * changes the packet header but not the magic number,
		 * and some other versions with this magic number have
		 * some extra debugging information in the packet header;
		 * we'd have to use some hacks^H^H^H^H^Hheuristics to
		 * detect those variants.
		 *
		 * Ethereal does that, but it does so by trying to read
		 * the first two packets of the file with each of the
		 * record header formats.  That currently means it seeks
		 * backwards and retries the reads, which doesn't work
		 * on pipes.  We want to be able to read from a pipe, so
		 * that strategy won't work; we'd have to buffer some
		 * data ourselves and read from that buffer in order to
		 * make that work.
		 */
		p->sf.hdrsize = sizeof(struct pcap_sf_patched_pkthdr);
	} else
		p->sf.hdrsize = sizeof(struct pcap_sf_pkthdr);
	if (hdr.version_major < PCAP_VERSION_MAJOR) {
		snprintf(errbuf, PCAP_ERRBUF_SIZE, "archaic file format");
		goto bad;
	}
	p->tzoff = hdr.thiszone;
	p->snapshot = hdr.snaplen;
	p->linktype = linktype_to_dlt(hdr.linktype);
	p->sf.rfile = fp;
#ifndef WIN32
	p->bufsize = hdr.snaplen;
#else
	/* Allocate the space for pcap_pkthdr as well. It will be used by pcap_read_ex */
	p->bufsize = hdr.snaplen+sizeof(struct pcap_pkthdr);
#endif

	/* Align link header as required for proper data alignment */
	/* XXX should handle all types */
	switch (p->linktype) {

	case DLT_EN10MB:
		linklen = 14;
		break;

	case DLT_FDDI:
		linklen = 13 + 8;	/* fddi_header + llc */
		break;

	case DLT_NULL:
	default:
		linklen = 0;
		break;
	}

	if (p->bufsize < 0)
		p->bufsize = BPF_MAXBUFSIZE;
	p->sf.base = (u_char *)malloc(p->bufsize + BPF_ALIGNMENT);
	if (p->sf.base == NULL) {
		strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE);
		goto bad;
	}
	p->buffer = p->sf.base + BPF_ALIGNMENT - (linklen % BPF_ALIGNMENT);
	p->sf.version_major = hdr.version_major;
	p->sf.version_minor = hdr.version_minor;
#ifdef PCAP_FDDIPAD
	/* XXX padding only needed for kernel fcode */
	pcap_fddipad = 0;
#endif

	/*
	 * We interchanged the caplen and len fields at version 2.3,
	 * in order to match the bpf header layout.  But unfortunately
	 * some files were written with version 2.3 in their headers
	 * but without the interchanged fields.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -