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

📄 savefile.c

📁 该软件根据网络数据生成NetFlow记录。NetFlow可用于网络规划、负载均衡、安全监控等
💻 C
字号:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *                                                                            * *  Copyright 2005 University of Cambridge Computer Laboratory.               * *                                                                            * *  This file is part of Nprobe.                                              * *                                                                            * *  Nprobe is free software; you can redistribute it and/or modify it under   * *  the terms of the GNU General Public License as published by the Free      * *  Software Foundation; either version 2 of the License, or (at your         * *  option) any later version.                                                * *                                                                            * *  Nprobe is distributed in the hope that it will be useful, but WITHOUT     * *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     * *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License     * *  for more details.                                                         * *                                                                            * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **//* * Copyright (c) 1993, 1994, 1995, 1996, 1997 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * savefile.c - supports offline use of tcpdump *	Extraction/creation by Jeffrey Mogul, DECWRL *	Modified by Steve McCanne, LBL. * * Used to save the received packet headers, after filtering, to * a file, and then read them later. * The first record in the file contains saved values for the machine * dependent values so we can print the dump file on any architecture. */#ifndef lintstatic const char rcsid[] =    "@(#) $Header: savefile.c,v 1.37 97/10/15 21:58:58 leres Exp $ (LBL)";#endif#include <sys/types.h>#include <sys/time.h>#include <errno.h>#include <memory.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include "pcap-int.h"#include "gnuc.h"#ifdef HAVE_OS_PROTO_H#include "os-proto.h"#endif#ifdef ZFLAG#include "if_nprobe.h"#endif#define TCPDUMP_MAGIC 0xa1b2c3d4 #define TCPDUMP_MAGIC_LINUX 0xa1b2cd34/* * We use the "receiver-makes-right" approach to byte order, * because time is at a premium when we are writing the file. * In other words, the pcap_file_header and pcap_pkthdr, * records are written in host byte order. * Note that the packets are always written in network byte order. * * ntoh[ls] aren't sufficient because we might need to swap on a big-endian * machine (if the file was written in little-end order). */#define	SWAPLONG(y) \((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))#define	SWAPSHORT(y) \	( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) )#define SFERR_TRUNC		1#define SFERR_BADVERSION	2#define SFERR_BADF		3#define SFERR_EOF		4 /* not really an error, just a status */intsf_write_header(FILE *fp, int linktype, int thiszone, int snaplen){	struct pcap_file_header hdr;		hdr.magic = TCPDUMP_MAGIC_LINUX;	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 voidswap_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);}pcap_t *pcap_open_offline(const char *fname, char *errbuf){  register pcap_t *p;  register FILE *fp;  struct pcap_file_header hdr;  int linklen;    p = (pcap_t *)malloc(sizeof(*p));  if (p == NULL)     {      strcpy(errbuf, "out of swap");      return (NULL);    }    memset((char *)p, 0, sizeof(*p));  /*   * Set this field so we don't close stdin in pcap_close!   */  p->fd = -1;    if (fname[0] == '-' && fname[1] == '\0')    fp = stdin;  else     {      fp = fopen(fname, "r");      if (fp == NULL) 	{	  sprintf(errbuf, "%s: %s", fname, pcap_strerror(errno));	  goto bad;	}    }  if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1)     {      sprintf(errbuf, "fread: %s", pcap_strerror(errno));      goto bad;    }  if (hdr.magic != TCPDUMP_MAGIC)     {      p->sf.swapped = 1;      if (SWAPLONG(hdr.magic) != TCPDUMP_MAGIC) 	{	  p->sf.swapped = 0;	  p->sf.extended = 1;	  if (hdr.magic != TCPDUMP_MAGIC_LINUX) 	    {	      if (SWAPLONG(hdr.magic) != TCPDUMP_MAGIC_LINUX) 		{		  sprintf(errbuf, "bad dump file format");		  goto bad;		}	      p->sf.swapped = 1;	    }	}    }  if (p->sf.swapped)    swap_hdr(&hdr);      if (hdr.version_major < PCAP_VERSION_MAJOR)     {      sprintf(errbuf, "archaic file format");      goto bad;    }  p->tzoff = hdr.thiszone;  p->snapshot = hdr.snaplen;  p->linktype = hdr.linktype;  p->sf.rfile = fp;  p->bufsize = hdr.snaplen;    /* Align link header as required for proper data alignment */  /* XXX should handle all types */  switch (p->linktype)     {      #ifdef ZFLAG    case DLT_NPROBE:#endif    case DLT_EN10MB:      linklen = 14;      break;          case DLT_FDDI:      linklen = 13 + 8;	/* fddi_header + llc */      break;          case DLT_NULL:    default:      linklen = 0;      break;    }    p->sf.base = (u_char *)malloc(p->bufsize + BPF_ALIGNMENT);  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    return (p); bad:  free(p);  return (NULL);}/* * Read sf_readfile and return the next packet.  Return the header in hdr * and the contents in buf.  Return 0 on success, SFERR_EOF if there were * no more packets, and SFERR_TRUNC if a partial packet was encountered. */static intsf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen){  //static int pno;  FILE *fp = p->sf.rfile;    if (!p->sf.extended)     {      /* read BSD file on linux. */      if (fread((char *)hdr, sizeof(struct pcap_pkthdr)-8, 1, fp) != 1) 	{	  /* probably an EOF, though could be a truncated packet */	  return (1);	}      hdr->ifindex = 0;      hdr->protocol = 0;      hdr->pkt_type = 0;    }   else     {      /* read the stamp */      if (fread((char *)hdr, sizeof(struct pcap_pkthdr), 1, fp) != 1) 	{	  /* probably an EOF, though could be a truncated packet */	  return (1);	}    }  //printf("pkt %d\n", pno);  //pno += 1;    if (p->sf.swapped)     {      /* these were written in opposite byte order */      hdr->caplen = SWAPLONG(hdr->caplen);      hdr->len = SWAPLONG(hdr->len);      hdr->ts.tv_sec = SWAPLONG(hdr->ts.tv_sec);      hdr->ts.tv_usec = SWAPLONG(hdr->ts.tv_usec);    }    /*   * 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.   */  if (p->sf.version_minor < 3 ||      (p->sf.version_minor == 3 && hdr->caplen > hdr->len))     {      int t = hdr->caplen;      hdr->caplen = hdr->len;      hdr->len = t;    }  //printf("caplen %u len %u\n", hdr->caplen, hdr->len);  if (hdr->caplen > buflen)     {      /*       * This can happen due to Solaris 2.3 systems tripping over the BUFMOD       * problem and not setting the snapshot correctly in the savefile       * header.  If the caplen isn't grossly wrong, try to salvage.       */      static u_char *tp = NULL;      static int tsize = 0;            if (hdr->caplen > 65535) 	{	  sprintf(p->errbuf, "bogus savefile header");	  return (-1);	}      if (tsize < hdr->caplen) 	{	  tsize = ((hdr->caplen + 1023) / 1024) * 1024;	  if (tp != NULL)	    free((u_char *)tp);	  tp = (u_char *)malloc(tsize);	  if (tp == NULL) 	    {	      tsize = 0;	      sprintf(p->errbuf, "BUFMOD hack malloc");	      return (-1);	    }	}      if (fread((char *)tp, hdr->caplen, 1, fp) != 1) 	{	  sprintf(p->errbuf, "truncated dump file");	  return (-1);	}      /*       * We can only keep up to buflen bytes.  Since caplen > buflen is exactly       * how we got here, we know we can only keep the first buflen bytes and       * must drop the remainder.  Adjust caplen accordingly, so we don't get       * confused later as to how many bytes we have to play with.       */      hdr->caplen = buflen;      memcpy((char *)buf, (char *)tp, buflen);          }   else     {      /* read the packet itself */            if (fread((char *)buf, hdr->caplen, 1, fp) != 1) {	sprintf(p->errbuf, "truncated dump file");	return (-1);      }    }    return (0);}#ifdef ZFLAG extern int Zflag;#endif/* * Print out packets stored in the file initialized by sf_read_init(). * If cnt > 0, return after 'cnt' packets, otherwise continue until eof. */intpcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user){	struct bpf_insn *fcode = p->fcode.bf_insns;	int status = 0;	int n = 0;	while (status == 0) {int i;		struct pcap_pkthdr h;for (i = 0; i < p->bufsize; i++) p->buffer[i] = 0xff;		status = sf_next_packet(p, &h, p->buffer, p->bufsize);		if (status) {			if (status == 1)				return (0);			return (status);		}#ifdef ZFLAG		/* adjust for DEC collected FDDI traces */		if (Zflag)		  {		    p->buffer += 3;		    h.len -= 3;		    h.caplen -= 3;		  }#endif		if (fcode == NULL ||		    bpf_filter(fcode, p->buffer, h.len, h.caplen)) {			(*callback)(user, &h, p->buffer);			if (++n >= cnt && cnt > 0)				break;		}	}	/*XXX this breaks semantics tcpslice expects */	return (n);}/* * Output a packet to the initialized dump file. */voidpcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp){	register FILE *f;	f = (FILE *)user;	/* XXX we should check the return status */	(void)fwrite((char *)h, sizeof(*h), 1, f);	(void)fwrite((char *)sp, h->caplen, 1, f);}/* * Initialize so that sf_write() will output to the file named 'fname'. */pcap_dumper_t *pcap_dump_open(pcap_t *p, const char *fname){	FILE *f;	if (fname[0] == '-' && fname[1] == '\0')		f = stdout;	else {		f = fopen(fname, "w");		if (f == NULL) {			sprintf(p->errbuf, "%s: %s",			    fname, pcap_strerror(errno));			return (NULL);		}	}	(void)sf_write_header(f, p->linktype, p->tzoff, p->snapshot);	return ((pcap_dumper_t *)f);}voidpcap_dump_close(pcap_dumper_t *p){#ifdef notyet	if (ferror((FILE *)p))		return-an-error;	/* XXX should check return from fclose() too */#endif	(void)fclose((FILE *)p);}

⌨️ 快捷键说明

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