1 /*
2  * Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
3  *               2002, 2003, 2004
4  *	Ohio University.
5  *
6  * ---
7  *
8  * Starting with the release of tcptrace version 6 in 2001, tcptrace
9  * is licensed under the GNU General Public License (GPL).  We believe
10  * that, among the available licenses, the GPL will do the best job of
11  * allowing tcptrace to continue to be a valuable, freely-available
12  * and well-maintained tool for the networking community.
13  *
14  * Previous versions of tcptrace were released under a license that
15  * was much less restrictive with respect to how tcptrace could be
16  * used in commercial products.  Because of this, I am willing to
17  * consider alternate license arrangements as allowed in Section 10 of
18  * the GNU GPL.  Before I would consider licensing tcptrace under an
19  * alternate agreement with a particular individual or company,
20  * however, I would have to be convinced that such an alternative
21  * would be to the greater benefit of the networking community.
22  *
23  * ---
24  *
25  * This file is part of Tcptrace.
26  *
27  * Tcptrace was originally written and continues to be maintained by
28  * Shawn Ostermann with the help of a group of devoted students and
29  * users (see the file 'THANKS').  The work on tcptrace has been made
30  * possible over the years through the generous support of NASA GRC,
31  * the National Science Foundation, and Sun Microsystems.
32  *
33  * Tcptrace is free software; you can redistribute it and/or modify it
34  * under the terms of the GNU General Public License as published by
35  * the Free Software Foundation; either version 2 of the License, or
36  * (at your option) any later version.
37  *
38  * Tcptrace is distributed in the hope that it will be useful, but
39  * WITHOUT ANY WARRANTY; without even the implied warranty of
40  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
41  * General Public License for more details.
42  *
43  * You should have received a copy of the GNU General Public License
44  * along with Tcptrace (in the file 'COPYING'); if not, write to the
45  * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
46  * MA 02111-1307 USA
47  *
48  * Author:	Shawn Ostermann
49  * 		School of Electrical Engineering and Computer Science
50  * 		Ohio University
51  * 		Athens, OH
52  *		ostermann@cs.ohiou.edu
53  *		http://www.tcptrace.org/
54  */
55 #include "tcptrace.h"
56 static char const GCC_UNUSED copyright[] =
57     "@(#)Copyright (c) 2004 -- Ohio University.\n";
58 static char const GCC_UNUSED rcsid[] =
59     "@(#)$Header$";
60 
61 
62 /*
63  * nlanr - TSH specific file reading stuff
64  */
65 
66 /* TSH header format:
67  *        0                   1                   2                   3
68  *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
69  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
70  * 0  |                    timestamp (seconds)                        | Time
71  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
72  * 1  |  interface #  |          timestamp (microseconds)             |
73  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
74  * 2  |Version|  IHL  |Type of Service|          Total Length         | IP
75  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
76  * 3  |         Identification        |Flags|      Fragment Offset    |
77  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
78  * 4  |  Time to Live |    Protocol   |         Header Checksum       |
79  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
80  * 5  |                       Source Address                          |
81  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
82  * 6  |                    Destination Address                        |
83  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
84  * 7  |          Source Port          |       Destination Port        | TCP
85  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
86  * 8  |                        Sequence Number                        |
87  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
88  * 9  |                    Acknowledgment Number                      |
89  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
90  *    |  Data |           |U|A|P|R|S|F|                               |
91  * 10 | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
92  *    |       |           |G|K|H|T|N|N|                               |
93  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
94  */
95 
96 
97 
98 
99 
100 #ifdef GROK_NLANR
101 
102 /* Defining SYS_STDIN which is fp for Windows and stdin for all other systems */
103 #ifdef __WIN32
104 static FILE *fp;
105 #define SYS_STDIN fp
106 #else
107 #define SYS_STDIN stdin
108 #endif /* __WIN32 */
109 
110 /* information necessary to understand NLANL Tsh output */
111 #define TSH_DUMP_OFFSET 16
112 struct tsh_packet_header {
113     unsigned int	ts_secs;
114 #ifdef _BIT_FIELDS_LTOH
115     unsigned int	interface_id:8;
116     unsigned int	ts_usecs:24;
117 #else
118     unsigned int	ts_usecs:24;
119     unsigned int	interface_id:8;
120 #endif
121 };
122 
123 struct tsh_frame {
124     struct tsh_packet_header tph;
125     struct ip ip_header;
126     struct tcphdr tcp_header;  /* just the first 16 bytes present */
127 };
128 
129 
130 /* static buffers for reading */
131 static struct ether_header *pep;
132 
133 /* return the next packet header */
134 /* currently only works for ETHERNET */
135 static int
pread_nlanr(struct timeval * ptime,int * plen,int * ptlen,void ** pphys,int * pphystype,struct ip ** ppip,void ** pplast)136 pread_nlanr(
137     struct timeval	*ptime,
138     int		 	*plen,
139     int		 	*ptlen,
140     void		**pphys,
141     int			*pphystype,
142     struct ip		**ppip,
143     void		**pplast)
144 {
145     int rlen;
146     static struct tsh_frame hdr;
147     int packlen = sizeof(struct ip) + sizeof(struct tcphdr);
148     int hlen = 44;
149 
150     /* read the next frames */
151     if ((rlen=fread(&hdr,1,hlen,SYS_STDIN)) != hlen) {
152 	if (debug && (rlen != 0))
153 	    fprintf(stderr,"Bad tsh packet header (len:%d)\n", rlen);
154 	return(0);
155     }
156 
157     /* grab the time */
158     ptime->tv_sec  = hdr.tph.ts_secs;
159     ptime->tv_usec = hdr.tph.ts_usecs;
160 
161     /* truncated length is just an IP header and a TCP header */
162     *ptlen         = packlen;
163 
164     /* original length is from the IP header */
165     *plen          = hdr.ip_header.ip_len;
166 
167 
168     /* Here's the IP/TCP stuff */
169     *ppip  = &hdr.ip_header;
170 
171     /* Here's the last byte of the packet */
172     *pplast = (char *)(*ppip)+packlen-1;
173 
174     /* here's the (pseudo) ethernet header */
175     *pphys  = pep;
176     *pphystype = PHYS_ETHER;
177 
178     return(1);
179 }
180 
181 
182 
183 /*
184  * is_nlanr()   is the input file in tsh format??
185  */
is_nlanr(char * filename)186 pread_f *is_nlanr(char *filename)
187 {
188     struct tsh_frame tf;
189     int rlen;
190 
191 #ifdef __WIN32
192     if((fp = fopen(filename, "r")) == NULL) {
193        perror(filename);
194        exit(-1);
195     }
196 #endif /* __WIN32 */
197 
198     /* tsh is a little hard because there's no magic number */
199 
200 
201     /* read the tsh file header */
202     if ((rlen=fread(&tf,1,sizeof(tf),SYS_STDIN)) != sizeof(tf)) {
203 	/* not even a full frame */
204 	rewind(SYS_STDIN);
205 	return(NULL);
206     }
207     rewind(SYS_STDIN);
208 
209     if (debug) {
210 	printf("nlanr tsh ts_secs:   %d\n", tf.tph.ts_secs);
211 	printf("nlanr tsh ts_usecs:  %d\n", tf.tph.ts_usecs);
212 	printf("nlanr tsh interface: %d\n", tf.tph.interface_id);
213 	printf("nlanr sizeof(tf):    %d\n", sizeof(tf));
214 	printf("nlanr sizeof(tph):   %d\n", sizeof(tf.tph));
215 	if (debug > 1)
216 	    PrintRawDataHex("NLANR TSH header",&tf,(char *)&tf+39);
217     }
218 
219     /* quick heuristics */
220     if (((tf.ip_header.ip_v != 4) && (tf.ip_header.ip_v != 6))
221 	) {
222 	return(NULL);
223     }
224 
225 
226     /* OK, let's hope it's a tsh file */
227 
228 
229     /* there's no physical header present, so make up one */
230     pep = MallocZ(sizeof(struct ether_header));
231     pep->ether_type = htons(ETHERTYPE_IP);
232 
233     if (debug)
234 	fprintf(stderr,"TSH format, interface ID %d\n", tf.tph.interface_id);
235 
236 
237     return(pread_nlanr);
238 }
239 #endif /* GROK_NLANR */
240