Move frame_data_init() declaration to frame_data.h
[obnox/wireshark/wip.git] / epan / frame_data.c
1 /* frame_data.c
2  * Routines for packet disassembly
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <wiretap/wtap.h>
31 #include <epan/frame_data.h>
32 #include <epan/packet.h>
33 #include <epan/emem.h>
34 #include <epan/timestamp.h>
35 #include "cfile.h"
36
37 #include <glib.h>
38
39 /* Protocol-specific data attached to a frame_data structure - protocol
40    index and opaque pointer. */
41 typedef struct _frame_proto_data {
42   int proto;
43   void *proto_data;
44 } frame_proto_data;
45
46 /* XXX - I declared this static, because it only seems to be used by
47  * p_get_proto_data and p_add_proto_data
48  */
49 static gint p_compare(gconstpointer a, gconstpointer b)
50 {
51   const frame_proto_data *ap = (const frame_proto_data *)a;
52   const frame_proto_data *bp = (const frame_proto_data *)b;
53
54   if (ap -> proto > bp -> proto)
55     return 1;
56   else if (ap -> proto == bp -> proto)
57     return 0;
58   else
59     return -1;
60
61 }
62
63
64 void
65 p_add_proto_data(frame_data *fd, int proto, void *proto_data)
66 {
67   frame_proto_data *p1 = se_alloc(sizeof(frame_proto_data));
68
69   g_assert(p1 != NULL);
70
71   p1 -> proto = proto;
72   p1 -> proto_data = proto_data;
73
74   /* Add it to the GSLIST */
75
76   fd -> pfd = g_slist_insert_sorted(fd -> pfd,
77                                     (gpointer *)p1,
78                                     p_compare);
79
80 }
81
82 void *
83 p_get_proto_data(frame_data *fd, int proto)
84 {
85   frame_proto_data temp, *p1;
86   GSList *item;
87
88   temp.proto = proto;
89   temp.proto_data = NULL;
90
91   item = g_slist_find_custom(fd->pfd, (gpointer *)&temp, p_compare);
92
93   if (item) {
94     p1 = (frame_proto_data *)item->data;
95     return p1->proto_data;
96   }
97
98   return NULL;
99
100 }
101
102 void
103 p_remove_proto_data(frame_data *fd, int proto)
104 {
105   frame_proto_data temp;
106   GSList *item;
107
108   temp.proto = proto;
109   temp.proto_data = NULL;
110
111   item = g_slist_find_custom(fd->pfd, (gpointer *)&temp, p_compare);
112
113   if (item) {
114     fd->pfd = g_slist_remove(fd->pfd, item->data);
115   }
116 }
117
118 #define COMPARE_FRAME_NUM()     ((fdata1->num < fdata2->num) ? -1 : \
119                                  (fdata1->num > fdata2->num) ? 1 : \
120                                  0)
121
122 #define COMPARE_NUM(f)  ((fdata1->f < fdata2->f) ? -1 : \
123                          (fdata1->f > fdata2->f) ? 1 : \
124                          COMPARE_FRAME_NUM())
125
126 /* Compare time stamps.
127    A packet whose time is a reference time is considered to have
128    a lower time stamp than any frame with a non-reference time;
129    if both packets' times are reference times, we compare the
130    times of the packets. */
131 #define COMPARE_TS(ts) \
132                 ((fdata1->flags.ref_time && !fdata2->flags.ref_time) ? -1 : \
133                  (!fdata1->flags.ref_time && fdata2->flags.ref_time) ? 1 : \
134                  (fdata1->ts.secs < fdata2->ts.secs) ? -1 : \
135                  (fdata1->ts.secs > fdata2->ts.secs) ? 1 : \
136                  (fdata1->ts.nsecs < fdata2->ts.nsecs) ? -1 :\
137                  (fdata1->ts.nsecs > fdata2->ts.nsecs) ? 1 : \
138                  COMPARE_FRAME_NUM())
139
140 gint
141 frame_data_compare(const frame_data *fdata1, const frame_data *fdata2, int field)
142 {
143         switch (field) {
144                 case COL_NUMBER:
145                         return COMPARE_FRAME_NUM();
146
147                 case COL_CLS_TIME:
148                         switch (timestamp_get_type()) {
149                                 case TS_ABSOLUTE:
150                                 case TS_ABSOLUTE_WITH_DATE:
151                                 case TS_EPOCH:
152                                         return COMPARE_TS(abs_ts);
153
154                                 case TS_RELATIVE:
155                                         return COMPARE_TS(rel_ts);
156
157                                 case TS_DELTA:
158                                         return COMPARE_TS(del_cap_ts);
159
160                                 case TS_DELTA_DIS:
161                                         return COMPARE_TS(del_dis_ts);
162
163                                 case TS_NOT_SET:
164                                         return 0;
165                         }
166                         return 0;
167
168                 case COL_ABS_TIME:
169                 case COL_ABS_DATE_TIME:
170                         return COMPARE_TS(abs_ts);
171
172                 case COL_REL_TIME:
173                         return COMPARE_TS(rel_ts);
174
175                 case COL_DELTA_TIME:
176                         return COMPARE_TS(del_cap_ts);
177
178                 case COL_DELTA_TIME_DIS:
179                         return COMPARE_TS(del_dis_ts);
180
181                 case COL_PACKET_LENGTH:
182                         return COMPARE_NUM(pkt_len);
183
184                 case COL_CUMULATIVE_BYTES:
185                         return COMPARE_NUM(cum_bytes);
186
187         }
188         g_return_val_if_reached(0);
189 }
190
191 void
192 frame_data_init(frame_data *fdata, guint32 num,
193                 nstime_t *elapsed_time,
194                 const struct wtap_pkthdr *phdr, gint64 offset,
195                 guint32 *cum_bytes,
196                 nstime_t *first_ts,
197                 nstime_t *prev_dis_ts,
198                 nstime_t *prev_cap_ts)
199 {
200   fdata->next = NULL;
201   fdata->prev = NULL;
202   fdata->pfd = NULL;
203   fdata->num = num;
204   fdata->pkt_len = phdr->len;
205   *cum_bytes += phdr->len;
206   fdata->cum_bytes  = *cum_bytes;
207   fdata->cap_len = phdr->caplen;
208   fdata->file_off = offset;
209   /* To save some memory, we coarcese it into a gint8 */
210   g_assert(phdr->pkt_encap <= G_MAXINT8);
211   fdata->lnk_t = (gint8) phdr->pkt_encap;
212   fdata->abs_ts.secs = phdr->ts.secs;
213   fdata->abs_ts.nsecs = phdr->ts.nsecs;
214   fdata->flags.passed_dfilter = 0;
215   fdata->flags.encoding = CHAR_ASCII;
216   fdata->flags.visited = 0;
217   fdata->flags.marked = 0;
218   fdata->flags.ref_time = 0;
219   fdata->color_filter = NULL;
220
221   /* If we don't have the time stamp of the first packet in the
222      capture, it's because this is the first packet.  Save the time
223      stamp of this packet as the time stamp of the first packet. */
224   if (nstime_is_unset(first_ts)) {
225     *first_ts = fdata->abs_ts;
226   }
227
228   /* If we don't have the time stamp of the previous captured packet,
229      it's because this is the first packet.  Save the time
230      stamp of this packet as the time stamp of the previous captured
231      packet. */
232   if (nstime_is_unset(prev_cap_ts)) {
233     *prev_cap_ts = fdata->abs_ts;
234   }
235
236   /* Get the time elapsed between the first packet and this packet. */
237   nstime_delta(&fdata->rel_ts, &fdata->abs_ts, first_ts);
238
239   /* If it's greater than the current elapsed time, set the elapsed time
240      to it (we check for "greater than" so as not to be confused by
241      time moving backwards). */
242   if ((gint32)elapsed_time->secs < fdata->rel_ts.secs
243         || ((gint32)elapsed_time->secs == fdata->rel_ts.secs && (gint32)elapsed_time->nsecs < fdata->rel_ts.nsecs)) {
244     *elapsed_time = fdata->rel_ts;
245   }
246
247   /* If we don't have the time stamp of the previous displayed packet,
248      it's because this is the first packet that's being displayed.  Save the time
249      stamp of this packet as the time stamp of the previous displayed
250      packet. */
251   if (nstime_is_unset(prev_dis_ts))
252     *prev_dis_ts = fdata->abs_ts;
253
254   /* Get the time elapsed between the previous displayed packet and
255      this packet. */
256   nstime_delta(&fdata->del_dis_ts, &fdata->abs_ts, prev_dis_ts);
257
258   /* Get the time elapsed between the previous captured packet and
259      this packet. */
260   nstime_delta(&fdata->del_cap_ts, &fdata->abs_ts, prev_cap_ts);
261   *prev_cap_ts = fdata->abs_ts;
262 }
263
264 void
265 frame_data_cleanup(frame_data *fdata)
266 {
267   if (fdata->pfd)
268     g_slist_free(fdata->pfd);
269
270   fdata->pfd = NULL;
271 }
272