2 * Author: Gurvinder Singh <gurvindersinghdahiya@gmail.com>
3 * Fikling by Kacper Wyoscki
5 * Created on January 16, 2010, 1:18 PM
11 #include "util-cxt-queue.h"
16 /* alloc hash memory */
18 /* pre allocate conection trackers */
19 for (i
= 0; i
< CXT_DEFAULT_PREALLOC
; i
++) {
20 connection
*cxt
= connection_alloc();
22 printf("ERROR: connection_alloc failed: %s\n", strerror(errno
));
25 cxt_enqueue(&cxt_spare_q
,cxt
);
29 /* Allocate a connection */
30 connection
*connection_alloc(void)
34 cxt
= calloc(1, sizeof(connection
));
36 printf("calloc failed to allocate connection\n");
49 /* free the memory of a connection tracker */
50 void connection_free(connection
*cxt
)
56 void cxt_update_dst (connection
*cxt
, packetinfo
*pi
)
58 cxt
->d_tcpFlags
|= (pi
->tcph
? pi
->tcph
->t_flags
: 0x00);
59 cxt
->d_total_bytes
+= pi
->packet_bytes
;
60 cxt
->d_total_pkts
+= 1;
61 cxt
->last_pkt_time
= pi
->pheader
->ts
.tv_sec
;
63 if (!(cxt
->check
& CXT_DONT_CHECK_SERVER
)
64 && (cxt
->d_total_bytes
> MAX_BYTE_CHECK
65 || cxt
->d_total_pkts
> MAX_PKT_CHECK
)) {
66 cxt
->check
|= CXT_DONT_CHECK_SERVER
; // Don't check
72 void cxt_update_src (connection
*cxt
, packetinfo
*pi
)
74 cxt
->s_tcpFlags
|= (pi
->tcph
? pi
->tcph
->t_flags
: 0x00);
75 cxt
->s_total_bytes
+= pi
->packet_bytes
;
76 cxt
->s_total_pkts
+= 1;
77 cxt
->last_pkt_time
= pi
->pheader
->ts
.tv_sec
;
79 if (!(cxt
->check
& CXT_DONT_CHECK_CLIENT
)
80 && (cxt
->s_total_bytes
> MAX_BYTE_CHECK
81 || cxt
->s_total_pkts
> MAX_PKT_CHECK
)) {
82 cxt
->check
|= CXT_DONT_CHECK_CLIENT
; // Don't check
87 inline void cxt_update (packetinfo
*pi
)
89 connection
*cxt
= NULL
;
92 /* get our hash bucket and lock it */
93 if (pi
->ip4
!= NULL
) {
94 hash
= CXT_HASH4(PI_IP4SRC(pi
),PI_IP4DST(pi
));
95 hash
= hash
% BUCKET_SIZE
;
97 hash
= CXT_HASH6(&PI_IP6SRC(pi
),&PI_IP6DST(pi
));
98 hash
= hash
% BUCKET_SIZE
;
102 /* see if the bucket already has a connection */
104 printf ("bucket[%u] is empty...\n",hash
);
106 /* no, so get a new one */
107 cxt
= cxt_dequeue(&cxt_spare_q
);
109 cxt
= connection_alloc();
114 /* these are protected by the bucket lock */
118 /* got one, initialize and return */
120 bucket
[hash
] = cxt
; /* is this what is missing ???? */
121 cxt_requeue(cxt
, NULL
, &cxt_est_q
);
122 cxt_update_src(cxt
, pi
);
127 /* ok, we have a flow in the bucket. Let's find out if it is our flow */
128 /* see if this is the flow we are looking for */
129 if (pi
->af
== AF_INET
) {
130 if (CMP_CXT4(cxt
, PI_IP4SRC(pi
), pi
->s_port
, PI_IP4DST(pi
), pi
->d_port
)) {
131 cxt_update_src(cxt
, pi
);
133 } else if (CMP_CXT4(cxt
, PI_IP4DST(pi
), pi
->d_port
, PI_IP4SRC(pi
), pi
->s_port
)) {
134 cxt_update_dst(cxt
, pi
);
137 } else if (pi
->af
== AF_INET6
){
138 if (CMP_CXT6(cxt
, &PI_IP6SRC(pi
), pi
->s_port
, &PI_IP6DST(pi
), pi
->d_port
)) {
139 cxt_update_src(cxt
, pi
);
141 } else if (CMP_CXT6(cxt
, &PI_IP6DST(pi
), pi
->d_port
, &PI_IP6SRC(pi
), pi
->s_port
)) {
142 cxt_update_dst(cxt
, pi
);
148 connection
*pcxt
= NULL
; /* previous connection */
150 while (cxt
!= NULL
) {
151 pcxt
= cxt
; /* pf is not locked at this point */
155 /* get us a new one and put it and the list tail */
156 cxt
= pcxt
->hnext
= cxt_dequeue(&cxt_spare_q
);
159 cxt
= connection_alloc();
168 /* initialize and return */
170 cxt_requeue(cxt
, NULL
, &cxt_est_q
);
172 cxt_update_src(cxt
, pi
);
177 if (pi
->af
== AF_INET
) {
178 if (CMP_CXT4(cxt
, PI_IP4SRC(pi
), pi
->s_port
, PI_IP4DST(pi
), pi
->d_port
)) {
179 cxt_update_src(cxt
, pi
);
181 } else if (CMP_CXT4(cxt
, PI_IP4DST(pi
), pi
->d_port
, PI_IP4SRC(pi
), pi
->s_port
)) {
182 cxt_update_dst(cxt
, pi
);
185 } else if (pi
->af
== AF_INET6
) {
186 if (CMP_CXT6(cxt
, &PI_IP6SRC(pi
), pi
->s_port
, &PI_IP6DST(pi
), pi
->d_port
)) {
187 cxt_update_src(cxt
, pi
);
189 } else if (CMP_CXT6(cxt
, &PI_IP6DST(pi
), pi
->d_port
, &PI_IP6SRC(pi
), pi
->s_port
)) {
190 cxt_update_dst(cxt
, pi
);
195 /* we found our flow, lets put it on top of the
196 * hash list -- this rewards active flows */
197 if (cxt
->hnext
) cxt
->hnext
->hprev
= cxt
->hprev
;
198 if (cxt
->hprev
) cxt
->hprev
->hnext
= cxt
->hnext
;
205 /* found our connection */
210 /* not found, try the next... */
214 /* The 'root' connection was our connection, return it. */
222 while((cxt
= cxt_dequeue(&cxt_spare_q
))) {
223 connection_free(cxt
);
226 while((cxt
= cxt_dequeue(&cxt_est_q
))) {
227 connection_free(cxt
);
230 printf("\nqueue memory has been cleared");
233 /* initialize the connection from the first packet we see from it. */
235 void cxt_new (connection
*cxt
, packetinfo
*pi
)
237 printf("New connection...\n");
238 extern u_int64_t cxtrackerid
;
241 cxt
->cxid
= cxtrackerid
;
243 cxt
->s_tcpFlags
|= (pi
->tcph
? pi
->tcph
->t_flags
: 0x00);
244 cxt
->s_total_bytes
= pi
->packet_bytes
;
245 cxt
->s_total_pkts
= 1;
246 cxt
->start_time
= pi
->pheader
->ts
.tv_sec
;
247 cxt
->last_pkt_time
= pi
->pheader
->ts
.tv_sec
;
248 if(pi
->af
== AF_INET
){
249 IP4ADDR(&cxt
->s_ip
) = PI_IP4SRC(pi
);
250 IP4ADDR(&cxt
->d_ip
) = PI_IP4DST(pi
);
252 cxt
->s_ip
= PI_IP6SRC(pi
);
253 cxt
->d_ip
= PI_IP6DST(pi
);
255 cxt
->s_port
= pi
->s_port
;
256 cxt
->d_port
= pi
->d_port
;
257 cxt
->proto
= (pi
->ip4
? pi
->ip4
->ip_p
: pi
->ip6
->next
);
265 void reverse_pi_cxt(packetinfo
*pi
)
270 struct in6_addr tmp_ip
;
276 /* First we chang the cxt */
278 tmpFlags
= cxt
->s_tcpFlags
;
279 tmp_pkts
= cxt
->s_total_pkts
;
280 tmp_bytes
= cxt
->s_total_bytes
;
282 tmp_port
= cxt
->s_port
;
285 cxt
->s_tcpFlags
= cxt
->d_tcpFlags
;
286 cxt
->s_total_pkts
= cxt
->d_total_pkts
;
287 cxt
->s_total_bytes
= cxt
->d_total_bytes
;
288 cxt
->s_ip
= cxt
->d_ip
;
289 cxt
->s_port
= cxt
->d_port
;
292 cxt
->d_tcpFlags
= tmpFlags
;
293 cxt
->d_total_pkts
= tmp_pkts
;
294 cxt
->d_total_bytes
= tmp_bytes
;
296 cxt
->d_port
= tmp_port
;
298 /* Not taking any chances :P */
299 cxt
->c_asset
= cxt
->s_asset
= NULL
;
302 /* Then we change pi */
303 if (pi
->sc
== SC_CLIENT
) pi
->sc
= SC_SERVER
;
304 else pi
->sc
= SC_CLIENT
;