1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2009 Benjamin Poirier <benjamin.poirier@polymtl.ca>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23 #include <arpa/inet.h>
32 #include "data_structures_tcp.h"
36 #define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
39 // TCP sequence numbers use clock arithmetic, these comparison functions take
41 #define SEQ_LT(a,b) ((int32_t)((a)-(b)) < 0)
42 #define SEQ_LEQ(a,b) ((int32_t)((a)-(b)) <= 0)
43 #define SEQ_GT(a,b) ((int32_t)((a)-(b)) > 0)
44 #define SEQ_GEQ(a,b) ((int32_t)((a)-(b)) >= 0)
48 * Compare two ConnectionKey structures
51 * true if each field of the structure is equal
54 bool connectionKeyEqual(const ConnectionKey
* const a
, const
55 ConnectionKey
* const b
)
57 if (a
->saddr
== b
->saddr
&& a
->daddr
== b
->daddr
&& a
->source
== b
->source
58 && a
->dest
== b
->dest
)
70 * Check if a packet is an acknowledge of another packet.
73 * ackPacket packet that is the confirmation
74 * ackedPacket packet that contains the original data, both packets have to
75 * come from the same direction of the same connection
77 bool isAcking(const Packet
* const ackPacket
, const Packet
* const
80 if (SEQ_GT(ackPacket
->inE
->packetKey
->ack_seq
,
81 ackedPacket
->inE
->packetKey
->seq
))
93 * Convert an IP address from 32 bit form to dotted quad
96 * str: A preallocated string of length >= 17
99 void convertIP(char* const str
, const uint32_t addr
)
101 struct in_addr iaddr
;
103 iaddr
.s_addr
= htonl(addr
);
104 strcpy(str
, inet_ntoa(iaddr
));
109 * Print the content of a Packet structure
111 void printPacket(const Packet
* const packet
)
113 char saddr
[17], daddr
[17];
114 PacketKey
* packetKey
;
116 packetKey
= packet
->inE
->packetKey
;
118 convertIP(saddr
, packetKey
->connectionKey
.saddr
);
119 convertIP(daddr
, packetKey
->connectionKey
.daddr
);
120 g_debug("%s:%u to %s:%u tot_len: %u ihl: %u seq: %u ack_seq: %u doff: %u "
121 "ack: %u rst: %u syn: %u fin: %u", saddr
,
122 packetKey
->connectionKey
.source
, daddr
, packetKey
->connectionKey
.dest
,
123 packetKey
->tot_len
, packetKey
->ihl
, packetKey
->seq
,
124 packetKey
->ack_seq
, packetKey
->doff
, packetKey
->ack
, packetKey
->rst
,
125 packetKey
->syn
, packetKey
->fin
);
130 * A GHashFunc for g_hash_table_new()
132 * This function is for indexing netEvents in unMatched lists. All fields of
133 * the corresponding packet must match for two keys to be equal.
138 guint
ghfPacketKeyHash(gconstpointer key
)
145 a
= p
->connectionKey
.source
+ (p
->connectionKey
.dest
<< 16);
146 b
= p
->connectionKey
.saddr
;
147 c
= p
->connectionKey
.daddr
;
150 a
+= p
->ihl
+ (p
->tot_len
<< 8) + (p
->doff
<< 24);
155 a
+= p
->ack
+ (p
->rst
<< 8) + (p
->syn
<< 16) + (p
->fin
<< 24);
163 * A GEqualFunc for g_hash_table_new()
165 * This function is for indexing netEvents in unMatched lists. All fields of
166 * the corresponding packet must match for two keys to be equal.
172 * TRUE if both values are equal
174 gboolean
gefPacketKeyEqual(gconstpointer a
, gconstpointer b
)
176 const PacketKey
* pA
, * pB
;
178 pA
= ((PacketKey
*) a
);
179 pB
= ((PacketKey
*) b
);
181 if (connectionKeyEqual(&pA
->connectionKey
, &pB
->connectionKey
) &&
182 pA
->ihl
== pB
->ihl
&&
183 pA
->tot_len
== pB
->tot_len
&&
184 pA
->seq
== pB
->seq
&&
185 pA
->ack_seq
== pB
->ack_seq
&&
186 pA
->doff
== pB
->doff
&&
187 pA
->ack
== pB
->ack
&&
188 pA
->rst
== pB
->rst
&&
189 pA
->syn
== pB
->syn
&&
202 * A GDestroyNotify function for g_hash_table_new_full()
207 void gdnDestroyNetEvent(gpointer data
)
209 destroyNetEvent((NetEvent
*) data
);
214 * A GDestroyNotify function for g_hash_table_new_full()
217 * data: GQueue* list[Packet]
219 void gdnPacketListDestroy(gpointer data
)
223 list
= (GQueue
*) data
;
225 g_debug("XXXX gdnPacketListDestroy\n");
227 g_queue_foreach(list
, &gfPacketDestroy
, NULL
);
233 * A GFunc for g_queue_foreach()
236 * data Packet*, packet to destroy
239 void gfPacketDestroy(gpointer data
, gpointer user_data
)
241 g_debug("XXXX gfPacketDestroy\n");
242 destroyPacket((Packet
*) data
);
247 * Free the memory used by a Packet and the memory of all its associated
250 void destroyPacket(Packet
* const packet
)
252 g_debug("XXXX destroyPacket ");
256 g_assert(packet
->inE
!= NULL
&& packet
->outE
!= NULL
&&
257 packet
->inE
->packetKey
== packet
->outE
->packetKey
);
259 packet
->outE
->packetKey
= NULL
;
261 destroyNetEvent(packet
->inE
);
262 destroyNetEvent(packet
->outE
);
264 if (packet
->acks
!= NULL
)
266 g_queue_foreach(packet
->acks
, &gfPacketDestroy
, NULL
);
267 g_queue_free(packet
->acks
);
275 * Free the memory used by a NetEvent
277 void destroyNetEvent(NetEvent
* const event
)
279 g_debug("XXXX destroyNetEvent\n");
281 if (event
->packetKey
!= NULL
)
283 free(event
->packetKey
);
290 * A GCompareFunc for g_queue_find_custom()
293 * a Packet* acked packet
294 * b Packet* ack packet
299 gint
gcfPacketAckCompare(gconstpointer a
, gconstpointer b
)
301 if (isAcking((const Packet
*) b
, (const Packet
*) a
))
313 * A GHashFunc for g_hash_table_new()
315 * Hash TCP connection keys. Here are a few possible implementations:
317 * 2.4 kernels used tcp_hashfn()
319 * I've seen something about an XOR hash:
320 * http://tservice.net.ru/~s0mbre/blog/2006/05/14#2006_05_14:
321 * unsigned int h = (laddr ^ lport) ^ (faddr ^ fport);
326 * In 2.6 kernels, inet_ehashfn() handles connection hashing with the help of
327 * Jenkins hashing, jhash.h
329 * This function uses jenkins hashing. The hash is not the same for packets in
330 * opposite directions of the same connection. (Hence the name
331 * connection*key*hash)
336 guint
ghfConnectionKeyHash(gconstpointer key
)
338 ConnectionKey
* connectionKey
;
341 connectionKey
= (ConnectionKey
*) key
;
343 a
= connectionKey
->source
+ (connectionKey
->dest
<< 16);
344 b
= connectionKey
->saddr
;
345 c
= connectionKey
->daddr
;
353 * A GEqualFunc for g_hash_table_new()
356 * a, b ConnectionKey*
359 * TRUE if both values are equal
361 gboolean
gefConnectionKeyEqual(gconstpointer a
, gconstpointer b
)
363 // Two packets in the same direction
364 if (connectionKeyEqual((const ConnectionKey
*) a
, (const ConnectionKey
*) b
))
376 * A GDestroyNotify function for g_hash_table_new_full()
379 * data: ConnectionKey*
381 void gdnConnectionKeyDestroy(gpointer data
)
383 free((ConnectionKey
*) data
);
This page took 0.03803 seconds and 4 git commands to generate.