Removal of the old packet-list in favor of the new packet list.
[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 void
64 p_add_proto_data(frame_data *fd, int proto, void *proto_data)
65 {
66   frame_proto_data *p1 = se_alloc(sizeof(frame_proto_data));
67
68   p1->proto = proto;
69   p1->proto_data = proto_data;
70
71   /* Add it to the GSLIST */
72
73   fd -> pfd = g_slist_insert_sorted(fd -> pfd,
74                     (gpointer *)p1,
75                     p_compare);
76 }
77
78 void *
79 p_get_proto_data(frame_data *fd, int proto)
80 {
81   frame_proto_data temp, *p1;
82   GSList *item;
83
84   temp.proto = proto;
85   temp.proto_data = NULL;
86
87   item = g_slist_find_custom(fd->pfd, (gpointer *)&temp, p_compare);
88
89   if (item) {
90     p1 = (frame_proto_data *)item->data;
91     return p1->proto_data;
92   }
93
94   return NULL;
95
96 }
97
98 void
99 p_remove_proto_data(frame_data *fd, int proto)
100 {
101   frame_proto_data temp;
102   GSList *item;
103
104   temp.proto = proto;
105   temp.proto_data = NULL;
106
107   item = g_slist_find_custom(fd->pfd, (gpointer *)&temp, p_compare);
108
109   if (item) {
110     fd->pfd = g_slist_remove(fd->pfd, item->data);
111   }
112 }
113
114 #define COMPARE_FRAME_NUM()     ((fdata1->num < fdata2->num) ? -1 : \
115                                  (fdata1->num > fdata2->num) ? 1 : \
116                                  0)
117
118 #define COMPARE_NUM(f)  ((fdata1->f < fdata2->f) ? -1 : \
119                          (fdata1->f > fdata2->f) ? 1 : \
120                          COMPARE_FRAME_NUM())
121
122 /* Compare time stamps.
123    A packet whose time is a reference time is considered to have
124    a lower time stamp than any frame with a non-reference time;
125    if both packets' times are reference times, we compare the
126    times of the packets. */
127 #define COMPARE_TS(ts) \
128                 ((fdata1->flags.ref_time && !fdata2->flags.ref_time) ? -1 : \
129                  (!fdata1->flags.ref_time && fdata2->flags.ref_time) ? 1 : \
130                  (fdata1->ts.secs < fdata2->ts.secs) ? -1 : \
131                  (fdata1->ts.secs > fdata2->ts.secs) ? 1 : \
132                  (fdata1->ts.nsecs < fdata2->ts.nsecs) ? -1 :\
133                  (fdata1->ts.nsecs > fdata2->ts.nsecs) ? 1 : \
134                  COMPARE_FRAME_NUM())
135
136 gint
137 frame_data_compare(const frame_data *fdata1, const frame_data *fdata2, int field)
138 {
139     switch (field) {
140         case COL_NUMBER:
141             return COMPARE_FRAME_NUM();
142
143         case COL_CLS_TIME:
144             switch (timestamp_get_type()) {
145                 case TS_ABSOLUTE:
146                 case TS_ABSOLUTE_WITH_DATE:
147                 case TS_EPOCH:
148                     return COMPARE_TS(abs_ts);
149
150                 case TS_RELATIVE:
151                     return COMPARE_TS(rel_ts);
152
153                 case TS_DELTA:
154                     return COMPARE_TS(del_cap_ts);
155
156                 case TS_DELTA_DIS:
157                     return COMPARE_TS(del_dis_ts);
158
159                 case TS_NOT_SET:
160                     return 0;
161             }
162             return 0;
163
164         case COL_ABS_TIME:
165         case COL_ABS_DATE_TIME:
166             return COMPARE_TS(abs_ts);
167
168         case COL_REL_TIME:
169             return COMPARE_TS(rel_ts);
170
171         case COL_DELTA_TIME:
172             return COMPARE_TS(del_cap_ts);
173
174         case COL_DELTA_TIME_DIS:
175             return COMPARE_TS(del_dis_ts);
176
177         case COL_PACKET_LENGTH:
178             return COMPARE_NUM(pkt_len);
179
180         case COL_CUMULATIVE_BYTES:
181             return COMPARE_NUM(cum_bytes);
182
183     }
184     g_return_val_if_reached(0);
185 }
186
187 void
188 frame_data_init(frame_data *fdata, guint32 num,
189                 const struct wtap_pkthdr *phdr, gint64 offset,
190                 guint32 cum_bytes)
191 {
192   fdata->next = NULL;
193   fdata->prev = NULL;
194   fdata->pfd = NULL;
195   fdata->num = num;
196   fdata->pkt_len = phdr->len;
197   fdata->cum_bytes = cum_bytes + phdr->len;
198   fdata->cap_len = phdr->caplen;
199   fdata->file_off = offset;
200   /* To save some memory, we coerce it into a gint16 */
201   g_assert(phdr->pkt_encap <= G_MAXINT16);
202   fdata->lnk_t = (gint16) phdr->pkt_encap;
203   fdata->abs_ts.secs = phdr->ts.secs;
204   fdata->abs_ts.nsecs = phdr->ts.nsecs;
205   fdata->flags.passed_dfilter = 0;
206   fdata->flags.encoding = PACKET_CHAR_ENC_CHAR_ASCII;
207   fdata->flags.visited = 0;
208   fdata->flags.marked = 0;
209   fdata->flags.ref_time = 0;
210   fdata->flags.ignored = 0;
211   fdata->color_filter = NULL;
212   fdata->col_text_len = NULL;
213   fdata->col_text = NULL;
214 }
215
216 void
217 frame_data_set_before_dissect(frame_data *fdata,
218                 nstime_t *elapsed_time,
219                 nstime_t *first_ts,
220                 nstime_t *prev_dis_ts,
221                 nstime_t *prev_cap_ts)
222 {
223   /* If we don't have the time stamp of the first packet in the
224      capture, it's because this is the first packet.  Save the time
225      stamp of this packet as the time stamp of the first packet. */
226   if (nstime_is_unset(first_ts))
227     *first_ts = fdata->abs_ts;
228
229   /* if this frames is marked as a reference time frame, reset
230      firstsec and firstusec to this frame */
231   if(fdata->flags.ref_time)
232     *first_ts = fdata->abs_ts;
233
234   /* If we don't have the time stamp of the previous captured packet,
235      it's because this is the first packet.  Save the time
236      stamp of this packet as the time stamp of the previous captured
237      packet. */
238   if (nstime_is_unset(prev_cap_ts))
239     *prev_cap_ts = fdata->abs_ts;
240
241   /* Get the time elapsed between the first packet and this packet. */
242   nstime_delta(&fdata->rel_ts, &fdata->abs_ts, first_ts);
243
244   /* If it's greater than the current elapsed time, set the elapsed time
245      to it (we check for "greater than" so as not to be confused by
246      time moving backwards). */
247   if ((gint32)elapsed_time->secs < fdata->rel_ts.secs
248     || ((gint32)elapsed_time->secs == fdata->rel_ts.secs && (gint32)elapsed_time->nsecs < fdata->rel_ts.nsecs)) {
249     *elapsed_time = fdata->rel_ts;
250   }
251
252   /* Get the time elapsed between the previous displayed packet and
253      this packet. */
254   if (nstime_is_unset(prev_dis_ts))
255     /* If we don't have the time stamp of the previous displayed packet,
256        it's because we have no displayed packets prior to this.
257        Set the delta time to zero. */
258     nstime_set_zero(&fdata->del_dis_ts);
259   else
260     nstime_delta(&fdata->del_dis_ts, &fdata->abs_ts, prev_dis_ts);
261
262   /* Get the time elapsed between the previous captured packet and
263      this packet. */
264   nstime_delta(&fdata->del_cap_ts, &fdata->abs_ts, prev_cap_ts);
265   *prev_cap_ts = fdata->abs_ts;
266 }
267
268 void
269 frame_data_set_after_dissect(frame_data *fdata,
270                 guint32 *cum_bytes,
271                 nstime_t *prev_dis_ts)
272 {
273   /* This frame either passed the display filter list or is marked as
274      a time reference frame.  All time reference frames are displayed
275      even if they dont pass the display filter */
276   if(fdata->flags.ref_time){
277     /* if this was a TIME REF frame we should reset the cul bytes field */
278     *cum_bytes = fdata->pkt_len;
279     fdata->cum_bytes = *cum_bytes;
280   } else {
281     /* increase cum_bytes with this packets length */
282     *cum_bytes += fdata->pkt_len;
283     fdata->cum_bytes = *cum_bytes;
284   }
285
286   /* Set the time of the previous displayed frame to the time of this
287      frame. */
288   *prev_dis_ts = fdata->abs_ts;
289 }
290
291 void
292 frame_data_cleanup(frame_data *fdata)
293 {
294   if (fdata->pfd)
295     g_slist_free(fdata->pfd);
296
297   fdata->pfd = NULL;
298 }
299