/*
* tcpstream - Firestorm TCP state tracking implementation.
* Copyright (c) 2002 Gianni Tedesco <gianni@scaramanga.co.uk>
* Released under the terms of the GNU GPL v2
*
* TODO:
* o Configure the timeouts
* o Implement timeouts for SYN2/FIN states
* o Implement TIME_WAIT states
* o Re-order out-of-order transmissions
* o Intelligent stream reassembly
* o Support sack
* o Connection re-sync
* o Connection pickup ?
*
* Should CORRECTLY cope with:
* o Re-transmissions
* o Bad TCP or IP checksum evasion
* o Broadcast/Multicast packets
* o PAWS (rfc1323) evasion
*/
#ifndef DONT_INLINE
#define __INLINE__ static inline
#else
#define __INLINE__ static
#endif
#ifndef STATE_DEBUG
#define dmesg(x...)
#else
#define dmesg mesg
static char *state_str[]={
"CLOSED",
"ESTABLISHED",
"SYN_SENT",
"SYN_RECV",
"FIN_WAIT1",
"FIN_WAIT2",
"TCP_TIME_WAIT",
"TCP_CLOSE",
"TCP_CLOSE_WAIT",
"TCP_LAST_ACK",
"TCP_LISTEN",
"TCP_CLOSING"
};
#endif
#include <cleanup.h>
#include "tcpip.h"
#define TCP_HZ 100
#define TCP_PAWS_24DAYS (60 * 60 * 24 * 24)
#define TCP_PAWS_MSL 60
#define TCP_PAWS_WINDOW 60
#define TCP_TMO_SYN1 (90*TCP_HZ)
/* Configuration */
unsigned int tcp_minttl=0;
unsigned int tcp_numstreams=2048;
unsigned int tcp_numflows=1024;
unsigned int tcp_reassemble=0;
unsigned int tcp_stateful=0;
struct arg tcpstream_args[]={
{"minttl", ARGTYPE_PUINT, NULL, {vp_uint:&tcp_minttl}},
{"num_streams", ARGTYPE_PBYTES, NULL, {vp_bytes:&tcp_numstreams}},
{"num_flows", ARGTYPE_PBYTES, NULL, {vp_bytes:&tcp_numflows}},
{"reassemble", ARGTYPE_PBOOL, NULL, {vp_bool:&tcp_reassemble}},
{NULL, ARGTYPE_NOP, NULL}
};
/* Token bucket for TCP state violations */
struct tokenbucket tcpstream_tb={
.cost=(RATE_SEC/1), /* 1 alert per second */
.burst=(RATE_SEC/1)*10, /* a burst of 10 alerts per second */
};
/* Token bucket for ICMP trying to fiddle with TCP state */
struct tokenbucket icmperr_tb={
.cost=(RATE_SEC/1), /* 1 alert per second */
.burst=(RATE_SEC/1)*10, /* a burst of 10 alerts per second */
};
/* Alert generator */
struct generator tcpstream_gen=init_generator("tcpstream", &tcpstream_tb);
struct generator icmperr_gen=init_generator("tcp.icmperr", &icmperr_tb);
/* Alerts */
struct alert alert_tcp1=init_alert("In-window SYN", 1, 0, 5);
struct alert alert_tcp2=init_alert("Data sent on closed stream", 2, 0, 5);
struct alert alert_tcp3=init_alert("PAWS discard", 3, 0, 5);
struct alert alert_icmp1=init_alert("ICMP error from interloper", 2, 0, 5);
struct alert alert_icmp2=init_alert("ICMP error on established connection", 2, 0, 5);
/* 1. Hash table for lookups -- O(n) in pathological cases, can be O(1) */
unsigned int tcp_hashsz=512;
struct tcp_session **tcp_hash=NULL;
/* 2. Slab cache for allocation -- O(1) */
union tcp_union *all_sessions=NULL;
union tcp_union *tcp_next=NULL;
/* 3. LRU list to evict oldest items -- O(1) */
struct tcp_lru lru={
.next=(struct tcp_session *)&lru,
.prev=(struct tcp_session *)&lru,
};
/* 4. Timeout list to evict entries on timeout */
struct tcp_tmo syn1={
.next=(struct tcp_session *)&syn1,
.prev=(struct tcp_session *)&syn1,
};
/* O(1) allocator for flows */
size_t flow_len=0;
void *flow_cache=NULL;
void *flow_next=NULL;
/* Statistics counters */
unsigned int tcp_packets=0;
unsigned int tcp_state_errs=0;
unsigned int tcp_broadcast=0;
unsigned int tcp_lowttl=0;
unsigned int tcp_timeouts=0;
unsigned int max_concurrent=0;
unsigned int num_active=0;
unsigned int max_flows=0;
unsigned int num_flows=0;
/* Wrap-safe seq/ack calculations */
__INLINE__ int before(u_int32_t s1, u_int32_t s2) {
return (int32_t)(s1-s2) < 0;
}
__INLINE__ int after(u_int32_t s1, u_int32_t s2) {
return (int32_t)(s2-s1) < 0;
}
__INLINE__ int between(u_int32_t s1, u_int32_t s2, u_int32_t s3) {
return s3 - s2 >= s1 - s2; /* is s2<=s1<=s3 ? */
}
__INLINE__ u_int32_t tcp_receive_window(struct tcp_stream *tp)
{
int32_t win=tp->rcv_wup+tp->rcv_wnd-tp->rcv_nxt;
if ( win<0 )
win=0;
return (u_int32_t)win;
}
__INLINE__ int tcp_sequence(struct tcp_stream *tp, u_int32_t seq, u_int32_t end_seq)
{
return !before(end_seq, tp->rcv_wup) &&
!after(seq, tp->rcv_nxt+tcp_receive_window(tp));
}
/* Convert 64bit timestamp to 32bit jiffies */
__INLINE__ unsigned int tcp_jiffies(struct packet *p)
{
unsigned int ret;
ret=p->time.tv_sec * TCP_HZ;
ret+=p->time.tv_usec / (1000000UL/TCP_HZ);
return ret;
}
/* TMO: Add a TCP session to the head of a timeout list */
__INLINE__ void tcp_tmo_add(struct tcp_tmo *l, struct tcp_session *s)
{
s->tmo_next=l->next;
s->tmo_prev=(struct tcp_session *)l;
l->next->tmo_prev=s;
l->next=s;
}
/* TMO: Remove a TCP session from a timeout list */
__INLINE__ void tcp_tmo_del(struct tcp_session *s)
{
if ( s->expire==0 )
return;
s->tmo_prev->tmo_next=s->tmo_next;
s->tmo_next->tmo_prev=s->tmo_prev;
s->tmo_prev=NULL;
s->tmo_next=NULL;
s->expire=0;
}
/* TMO: Check timeouts */
__INLINE__ void tcp_tmo_check(struct packet *pkt)
{
unsigned int now=tcp_jiffies(pkt);
while ( syn1.prev!=(struct tcp_session *)&syn1 ) {
if ( (int)syn1.prev->expire - (int)now > 0 )
return;
tcp_free(syn1.prev);
tcp_timeouts++;
}
}
/* LRU: Add a TCP session to the head of an LRU list */
__INLINE__ void tcp_lru_add(struct tcp_lru *l, struct tcp_session *s)
{
s->next=l->next;
s->prev=(struct tcp_session *)l;
l->next->prev=s;
l->next=s;
}
/* LRU: Remove a TCP session from an LRU */
__INLINE__ void tcp_lru_del(struct tcp_session *s)
{
s->prev->next=s->next;
s->next->prev=s->prev;
}
/* LRU: Move a TCP session to the front of an LRU */
__INLINE__ void tcp_lru_mtf(struct tcp_lru *l, struct tcp_session *s)
{
tcp_lru_del(s);
tcp_lru_add(l,s);
}
/* HASH: Unlink a session from the session hash */
__INLINE__ void tcp_hash_unlink(struct tcp_session *s)
{
if ( s->hash_next )
s->hash_next->hash_pprev=s->hash_pprev;
*s->hash_pprev=s->hash_next;
}
/* HASH: Link a session in to the TCP session hash */
__INLINE__ void tcp_hash_link(struct tcp_session *s)
{
if ( (s->hash_next=tcp_hash[s->bucket]) ) {
s->hash_next->hash_pprev=&s->hash_next;
}
tcp_hash[s->bucket]=s;
s->hash_pprev=&tcp_hash[s->bucket];
}
/* HASH: Move to front of hash collision chain */
__INLINE__ void tcp_hash_mtf(struct tcp_session *s)
{
tcp_hash_unlink(s);
tcp_hash_link(s);
}
/* Flow cache allocation, slab-cache stylee */
/* TODO: strategy for when maximum is reached, evict LRU? */
__INLINE__ void *tcp_flow_alloc(void)
{
void *ret=flow_next;
if ( !ret ) return ret;
flow_next=*(void **)flow_next;
if ( ++num_flows > max_flows )
max_flows=num_flows;
return ret;
}
__INLINE__ void tcp_flow_free(void *p)
{
*(void **)p=flow_next;
flow_next=p;
num_flows--;
}
/* Parse TCP options just for timestamps */
static int tcp_fast_options(struct pkt_tcphdr *t, u_int32_t *tsval)
{
char *tmp, *end;
/* Return if we don't have any */
if ( t->doff<<2 <= sizeof(struct pkt_tcphdr)) return 0;
/* Work out where they begin and end */
tmp=end=(char *)t;
tmp+=sizeof(struct pkt_tcphdr);
end+=(t->doff<<2);
while ( tmp<end ) {
if ( *tmp == TCPOPT_EOL || *tmp == TCPOPT_NOP ) {
tmp++;
continue;
}
if ( !(tmp+1 < end) ) break;
switch(*tmp) {
case TCPOPT_TIMESTAMP:
if ( !(tmp+10 < end) ) break;
*tsval=ntohl(*((u_int32_t *)(tmp+2)));
return 1;
}
tmp+=*(tmp+1);
}
return 0;
}
/* This will parse TCP options for SYN packets */
static void tcp_syn_options(struct tcp_stream *s, struct pkt_tcphdr *t, u_int32_t sec)
{
char *tmp, *end;
/* Return if we don't have any */
if ( t->doff<<2 <= sizeof(struct pkt_tcphdr)) return;
/* Work out where they begin and end */
tmp=end=(char *)t;
tmp+=sizeof(struct pkt_tcphdr);
end+=(t->doff<<2);
while ( tmp<end ) {
if ( *tmp == TCPOPT_EOL || *tmp == TCPOPT_NOP ) {
tmp++;
continue;
}
if ( !(tmp+1 < end) ) break;
switch(*tmp) {
case TCPOPT_SACK_PERMITTED:
s->flags|=TF_SACK_OK;
break;
case TCPOPT_TIMESTAMP:
s->flags|=TF_TSTAMP_OK;
/* Only check the bit we wa
Firestorm NIDS网络入侵检测系统
需积分: 10 164 浏览量
2008-12-03
15:23:33
上传
评论
收藏 458KB GZ 举报
hjwang009
- 粉丝: 0
- 资源: 2
最新资源
- Screenshot_20240427_031602.jpg
- 网页PDF_2024年04月26日 23-46-14_QQ浏览器网页保存_QQ浏览器转格式(6).docx
- 直接插入排序,冒泡排序,直接选择排序.zip
- 在排序2的基础上,再次对快排进行优化,其次增加快排非递归,归并排序,归并排序非递归版.zip
- 实现了7种排序算法.三种复杂度排序.三种nlogn复杂度排序(堆排序,归并排序,快速排序)一种线性复杂度的排序.zip
- 冒泡排序 直接选择排序 直接插入排序 随机快速排序 归并排序 堆排序.zip
- 课设-内部排序算法比较 包括冒泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、归并排序和堆排序.zip
- Python排序算法.zip
- C语言实现直接插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序、归并排序、计数排序,并带图详解.zip
- 常用工具集参考用于图像等数据处理
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈