/*
* Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
* 2002, 2003, 2004
* Ohio University.
*
* ---
*
* Starting with the release of tcptrace version 6 in 2001, tcptrace
* is licensed under the GNU General Public License (GPL). We believe
* that, among the available licenses, the GPL will do the best job of
* allowing tcptrace to continue to be a valuable, freely-available
* and well-maintained tool for the networking community.
*
* Previous versions of tcptrace were released under a license that
* was much less restrictive with respect to how tcptrace could be
* used in commercial products. Because of this, I am willing to
* consider alternate license arrangements as allowed in Section 10 of
* the GNU GPL. Before I would consider licensing tcptrace under an
* alternate agreement with a particular individual or company,
* however, I would have to be convinced that such an alternative
* would be to the greater benefit of the networking community.
*
* ---
*
* This file is part of Tcptrace.
*
* Tcptrace was originally written and continues to be maintained by
* Shawn Ostermann with the help of a group of devoted students and
* users (see the file 'THANKS'). The work on tcptrace has been made
* possible over the years through the generous support of NASA GRC,
* the National Science Foundation, and Sun Microsystems.
*
* Tcptrace 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.
*
* Tcptrace 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.
*
* You should have received a copy of the GNU General Public License
* along with Tcptrace (in the file 'COPYING'); if not, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Author: Shawn Ostermann
* School of Electrical Engineering and Computer Science
* Ohio University
* Athens, OH
* ostermann@cs.ohiou.edu
* http://www.tcptrace.org/
*/
#include "tcptrace.h"
static char const GCC_UNUSED copyright[] =
"@(#)Copyright (c) 2004 -- Ohio University.\n";
static char const GCC_UNUSED rcsid[] =
"@(#)$Header: /usr/local/cvs/tcptrace/netm.c,v 5.6 2003/11/19 14:38:03 sdo Exp $";
/*
* netm.c - NetMetrix specific file reading stuff
*/
#ifdef GROK_NETM
#define NETM_DUMP_OFFSET 0x1000
/* Defining SYS_STDIN which is fp for Windows and stdin for all other systems */
#ifdef __WIN32
static FILE *fp;
#define SYS_STDIN fp
#else
#define SYS_STDIN stdin
#endif /* __WIN32 */
/* netm file header format */
struct netm_header {
int netm_key;
int version;
};
#define NETM_VERSION_OLD 3
#define NETM_VERSION_NEW 4
#define NETM_KEY 0x6476
/* netm packet header format */
struct netm_packet_header_old {
int unused1;
int unused2;
int tstamp_secs;
int tstamp_usecs;
int tlen;
int len;
};
struct netm_packet_header {
int unused1;
int tstamp_secs;
int tstamp_usecs;
int unused2;
int unused3;
int len;
int tlen; /* truncated length */
int unused5;
};
/* netm packet header format */
int netm_oldversion;
/* static buffers for reading */
static struct ether_header *pep;
static int *pip_buf;
/* currently only works for ETHERNET */
static int
pread_netm(
struct timeval *ptime,
int *plen,
int *ptlen,
void **pphys,
int *pphystype,
struct ip **ppip,
void **pplast)
{
int packlen;
int rlen;
struct netm_packet_header hdr;
int len;
int hlen;
while (1) {
hlen = netm_oldversion?
(sizeof(struct netm_packet_header_old)):
(sizeof(struct netm_packet_header));
/* read the netm packet header */
if ((rlen=fread(&hdr,1,hlen,SYS_STDIN)) != hlen) {
if (rlen != 0)
fprintf(stderr,"Bad netm header\n");
return(0);
}
packlen = ntohl(hdr.tlen);
/* round up to multiple of 4 bytes */
len = (packlen + 3) & ~0x3;
/* read the ethernet header */
rlen=fread(pep,1,sizeof(struct ether_header),SYS_STDIN);
if (rlen != sizeof(struct ether_header)) {
fprintf(stderr,"Couldn't read ether header\n");
return(0);
}
/* read the rest of the packet */
len -= sizeof(struct ether_header);
if (len >= IP_MAXPACKET) {
/* sanity check */
fprintf(stderr,
"pread_netm: invalid next packet, IP len is %d, return EOF\n", len);
return(0);
}
if ((rlen=fread(pip_buf,1,len,SYS_STDIN)) != len) {
if (rlen != 0)
if (debug)
fprintf(stderr,
"Couldn't read %d more bytes, skipping last packet\n",
len);
return(0);
}
if (netm_oldversion) {
void *ptr;
struct netm_packet_header_old *pho;
ptr=&hdr;
pho = (struct netm_packet_header_old *) ptr;
ptime->tv_sec = ntohl(pho->tstamp_secs);
ptime->tv_usec = ntohl(pho->tstamp_usecs);
*plen = ntohl(pho->len);
*ptlen = ntohl(pho->tlen);
} else {
ptime->tv_sec = ntohl(hdr.tstamp_secs);
ptime->tv_usec = ntohl(hdr.tstamp_usecs);
*plen = ntohl(hdr.len);
*ptlen = ntohl(hdr.tlen);
}
*ppip = (struct ip *) pip_buf;
*pplast = (char *)pip_buf+packlen-sizeof(struct ether_header)-1; /* last byte in the IP packet */
*pphys = pep;
*pphystype = PHYS_ETHER;
/* if it's not IP, then skip it */
if ((ntohs(pep->ether_type) != ETHERTYPE_IP) &&
(ntohs(pep->ether_type) != ETHERTYPE_IPV6)) {
if (debug > 2)
fprintf(stderr,"pread_netm: not an IP packet\n");
continue;
}
return(1);
}
}
/* is the input file a NetMetrix format file?? */
pread_f *is_netm(char *filename)
{
struct netm_header nhdr;
int rlen;
#ifdef __WIN32
if((fp = fopen(filename, "r")) == NULL) {
perror(filename);
exit(-1);
}
#endif /* __WIN32 */
/* read the netm file header */
if ((rlen=fread(&nhdr,1,sizeof(nhdr),SYS_STDIN)) != sizeof(nhdr)) {
rewind(SYS_STDIN);
return(NULL);
}
rewind(SYS_STDIN);
/* convert to local byte order */
nhdr.netm_key = ntohl(nhdr.netm_key);
nhdr.version = ntohl(nhdr.version);
/* check for NETM */
if (nhdr.netm_key != NETM_KEY) {
return(NULL);
}
/* check version */
if (nhdr.version == NETM_VERSION_OLD)
netm_oldversion = 1;
else if (nhdr.version == NETM_VERSION_NEW)
netm_oldversion = 0;
else {
fprintf(stderr,"Bad NETM file header version: %d\n",
nhdr.version);
return(NULL);
}
if (debug)
printf("NETM file version: %d\n", nhdr.version);
/* ignore the header at the top */
if (fseek(SYS_STDIN,NETM_DUMP_OFFSET,SEEK_SET) == -1) {
perror("NETM lseek");
exit(-1);
}
/* OK, it's mine. Init some stuff */
pep = MallocZ(sizeof(struct ether_header));
pip_buf = MallocZ(IP_MAXPACKET);
return(pread_netm);
}
#endif /* GROK_NETM */
syntax highlighted by Code2HTML, v. 0.9.1