void end_sessions() { connection *cxt; time_t check_time; check_time = time(NULL); int xpir; uint32_t curcxt = 0; uint32_t expired = 0; for (cxt = cxt_est_q.bot; cxt != NULL;) { xpir = 0; curcxt++; /* * TCP */ if (cxt->proto == IP_PROTO_TCP) { /* * FIN from both sides */ if (cxt->s_tcpFlags & TF_FIN && cxt->d_tcpFlags & TF_FIN && (check_time - cxt->last_pkt_time) > 5) { xpir = 1; } /* * RST from eather side */ else if ((cxt->s_tcpFlags & TF_RST || cxt->d_tcpFlags & TF_RST) && (check_time - cxt->last_pkt_time) > 5) { xpir = 1; } // Commented out, since &TF_SYNACK is wrong! /* * if not a complete TCP 3-way handshake */ //else if ( !cxt->s_tcpFlags&TF_SYNACK || !cxt->d_tcpFlags&TF_SYNACK && (check_time - cxt->last_pkt_time) > 10) { // xpir = 1; //} /* * Ongoing timout */ //else if ( (cxt->s_tcpFlags&TF_SYNACK || cxt->d_tcpFlags&TF_SYNACK) && ((check_time - cxt->last_pkt_time) > 120)) { // xpir = 1; //} else if ((check_time - cxt->last_pkt_time) > TCP_TIMEOUT) { xpir = 1; } } /* * UDP */ else if (cxt->proto == IP_PROTO_UDP && (check_time - cxt->last_pkt_time) > 60) { xpir = 1; } /* * ICMP */ else if (cxt->proto == IP_PROTO_ICMP || cxt->proto == IP6_PROTO_ICMP) { if ((check_time - cxt->last_pkt_time) > 60) { xpir = 1; } } /* * All Other protocols */ else if ((check_time - cxt->last_pkt_time) > TCP_TIMEOUT) { xpir = 1; } if (xpir == 1) { expired++; xpir = 0; /* remove from the hash */ if (cxt->hprev) cxt->hprev->hnext = cxt->hnext; if (cxt->hnext) cxt->hnext->hprev = cxt->hprev; if (cxt->cb->cxt == cxt) cxt->cb->cxt = cxt->hnext; connection *tmp = cxt; cxt = cxt->prev; /* cxt_requeue(tmp, &cxt_est_q, &cxt_log_q); */ cxt_requeue(tmp, &cxt_est_q, &cxt_spare_q); CLEAR_CXT(tmp); //printf("[*] connection deleted!!!\n"); } else { cxt = cxt->prev; } } }
void cxtbuffer_write () { connection *cxt; cxt = NULL; cxt = cxt_dequeue(&cxt_log_q); if (cxt == NULL) { /* no more connections in the queue */ return; } connection *next; next = NULL; char stime[80], ltime[80]; time_t tot_time; static char src_s[INET6_ADDRSTRLEN]; static char dst_s[INET6_ADDRSTRLEN]; uint32_t s_ip_t, d_ip_t; FILE *cxtFile; char *cxtfname; cxtfname = ""; asprintf(&cxtfname, "%s/stats.%s.%ld", dpath, dev, tstamp); cxtFile = fopen(cxtfname, "w"); if (cxtFile == NULL) { printf("[*] ERROR: Cant open file %s\n",cxtfname); } else { while ( cxt != NULL ) { tot_time = cxt->last_pkt_time - cxt->start_time; strftime(stime, 80, "%F %H:%M:%S", gmtime(&cxt->start_time)); strftime(ltime, 80, "%F %H:%M:%S", gmtime(&cxt->last_pkt_time)); if ( verbose == 1 ) { if (cxt->ipversion == AF_INET) { if (!inet_ntop(AF_INET, & IP4ADDR(cxt->s_ip), src_s, INET_ADDRSTRLEN + 1 )) perror("Something died in inet_ntop"); if (!inet_ntop(AF_INET, & IP4ADDR(cxt->d_ip), dst_s, INET_ADDRSTRLEN + 1 )) perror("Something died in inet_ntop"); } else if (cxt->ipversion == AF_INET6) { if (!inet_ntop(AF_INET6, &cxt->s_ip, src_s, INET6_ADDRSTRLEN + 1 )) perror("Something died in inet_ntop"); if (!inet_ntop(AF_INET6, &cxt->d_ip, dst_s, INET6_ADDRSTRLEN + 1 )) perror("Something died in inet_ntop"); } printf("%ld%09ju|%s|%s|%ld|%u|%s|%u|",cxt->start_time,cxt->cxid,stime,ltime,tot_time, cxt->proto,src_s,ntohs(cxt->s_port)); printf("%s|%u|%ju|%ju|",dst_s,ntohs(cxt->d_port),cxt->s_total_pkts,cxt->s_total_bytes); printf("%ju|%ju|%u|%u\n",cxt->d_total_pkts,cxt->d_total_bytes,cxt->s_tcpFlags, cxt->d_tcpFlags); } if ( cxt->ipversion == AF_INET6 ) { if ( verbose != 1 ) { if (!inet_ntop(AF_INET6, &cxt->s_ip, src_s, INET6_ADDRSTRLEN + 1 )) perror("Something died in inet_ntop"); if (!inet_ntop(AF_INET6, &cxt->d_ip, dst_s, INET6_ADDRSTRLEN + 1 )) perror("Something died in inet_ntop"); } fprintf(cxtFile,"%ld%09ju|%s|%s|%ld|%u|%s|%u|",cxt->start_time,cxt->cxid,stime,ltime,tot_time, cxt->proto,src_s,ntohs(cxt->s_port)); fprintf(cxtFile,"%s|%u|%ju|%ju|",dst_s,ntohs(cxt->d_port),cxt->s_total_pkts, cxt->s_total_bytes); fprintf(cxtFile,"%ju|%ju|%u|%u\n",cxt->d_total_pkts,cxt->d_total_bytes,cxt->s_tcpFlags, cxt->d_tcpFlags); } connection *tmp = cxt; cxt = cxt_dequeue(&cxt_log_q); /* cxt_requeue(tmp, &cxt_est_q, &cxt_log_q); */ cxt_requeue(tmp, &cxt_log_q, &cxt_spare_q); } free(cxt); cxt=NULL; free(tmp); tmp=NULL; fclose(cxtFile); } cxt = NULL; free(cxtfname); }
inline void cxt_update (packetinfo *pi, uint32_t hash) { connection *cxt = NULL; int ret = 0; /* get our hash bucket and lock it */ cxtbucket *cb = &cxt_hash[hash]; /* see if the bucket already has a connection */ if (cb->cxt == NULL) { /* no, so get a new one */ cxt = cb->cxt = cxt_dequeue(&cxt_spare_q); if (cxt == NULL) { cxt = cb->cxt = connection_alloc(); if (cxt == NULL) { return; } } /* these are protected by the bucket lock */ cxt->hnext = NULL; cxt->hprev = NULL; /* got one, initialize and return */ cxt_new(cxt,pi); cxt_requeue(cxt, NULL, &cxt_est_q); cxt->cb = cb; cxt_update_src(cxt, pi); pi->cxt = cxt; return; } /* ok, we have a flow in the bucket. Let's find out if it is our flow */ cxt = cb->cxt; /* see if this is the flow we are looking for */ if (pi->af == AF_INET) { if (CMP_CXT4(cxt, PI_IP4SRC(pi), pi->s_port, PI_IP4DST(pi), pi->d_port)) { cxt_update_src(cxt, pi); ret = 1; } else if (CMP_CXT4(cxt, PI_IP4DST(pi), pi->d_port, PI_IP4SRC(pi), pi->s_port)) { cxt_update_dst(cxt, pi); ret = 1; } } else if (pi->af == AF_INET6){ if (CMP_CXT6(cxt, &PI_IP6SRC(pi), pi->s_port, &PI_IP6DST(pi), pi->d_port)) { cxt_update_src(cxt, pi); ret = 1; } else if (CMP_CXT6(cxt, &PI_IP6DST(pi), pi->d_port, &PI_IP6SRC(pi), pi->s_port)) { cxt_update_dst(cxt, pi); ret = 1; } } if (ret == 0) { connection *pcxt = NULL; /* previous connection */ while (cxt != NULL) { pcxt = cxt; /* pf is not locked at this point */ cxt = cxt->hnext; if (cxt == NULL) { /* get us a new one and put it and the list tail */ cxt = pcxt->hnext = cxt_dequeue(&cxt_spare_q); if (cxt == NULL) { cxt = cb->cxt = connection_alloc(); if (cxt == NULL) { return; } } cxt->hnext = NULL; cxt->hprev = pcxt; /* initialize and return */ cxt_new(cxt,pi); cxt_requeue(cxt, NULL, &cxt_est_q); cxt->cb = cb; cxt_update_src(cxt, pi); pi->cxt = cxt; return; } if (pi->af == AF_INET) { if (CMP_CXT4(cxt, PI_IP4SRC(pi), pi->s_port, PI_IP4DST(pi), pi->d_port)) { cxt_update_src(cxt, pi); ret = 1; } else if (CMP_CXT4(cxt, PI_IP4DST(pi), pi->d_port, PI_IP4SRC(pi), pi->s_port)) { cxt_update_dst(cxt, pi); ret = 1; } } else if (pi->af == AF_INET6) { if (CMP_CXT6(cxt, &PI_IP6SRC(pi), pi->s_port, &PI_IP6DST(pi), pi->d_port)) { cxt_update_src(cxt, pi); ret = 1; } else if (CMP_CXT6(cxt, &PI_IP6DST(pi), pi->d_port, &PI_IP6SRC(pi), pi->s_port)) { cxt_update_dst(cxt, pi); ret = 1; } } if ( ret != 0) { /* we found our flow, lets put it on top of the * hash list -- this rewards active flows */ if (cxt->hnext) cxt->hnext->hprev = cxt->hprev; if (cxt->hprev) cxt->hprev->hnext = cxt->hnext; cxt->hnext = cb->cxt; cxt->hprev = NULL; cb->cxt->hprev = cxt; cb->cxt = cxt; /* found our connection */ pi->cxt = cxt; return; } /* not found, try the next... */ } } pi->cxt = cxt; /* The 'root' connection was our connection, return it. */ return; }