====================
libnids-1.20
====================
1. Introduction
2. IP defragmentation
3. TCP stream assembly
4. A sample application
5. Basic libnids structures and functions
6. Misc useful hacks
1. Introduction
Declarations of data structures and functions defined by libnids are
gathered in include file "nids.h". An application which uses libnids
must include this file and must be linked with libnids.a (or
libnids.so.x.x).
An application's function main usually looks this way:
main()
{
application private processing, not related to libnids
optional modification of libnids parameters
if (!nids_init() ) something's wrong, terminate;
registration of callback functions
nids_run();
// not reached in normal situation
}
Another method is mentioned later.
2. IP defragmentation
In order to receive all IP packets seen by libnids (including
fragmented ones, packets with invalid checksum et cetera) a programmer
should define a callback function of the following type
void ip_frag_func(struct ip * a_packet, int len)
After calling nids_init, this function should be registered with
libnids:
nids_register_ip_frag(ip_frag_func);
Function ip_frag_func will be called from libnids; parameter a_packet
will point to a received datagram, len is the packet length.
Analogically, in order to receive only packets, which will be accepted
by a target host (that is, packets not fragmented or packets assembled
from fragments; a header correctness is verified) one should define a
callback function
void ip_func(struct ip * a_packet)
and register it with
nids_register_ip(ip_func);
3. TCP stream assembly
In order to receive data exchanged in a TCP stream, one must declare a
callback function
void tcp_callback(struct tcp_stream * ns, void ** param)
Structure tcp_stream provides all info on a TCP connection. For
instance, it contains two fields of type struct half_stream (named
client and server), each of them describing one side of a connection.
We'll explain all its fields later.
One of tcp_stream field is named nids_state. Behaviour of tcp_callback
depends on value of this field.
*
ns->nids_state==NIDS_JUST_EST
In this case, ns describes a connection which has just been
established. Tcp_callback must decide if it wishes to be notified
in future of arrival of data in this connection. All the
connection parameters are available (IP addresses, ports numbers
etc). If the connection is interesting, tcp_callback informs
libnids which data it wishes to receive (data to client, to
server, urgent data to client, urgent data to server). Then the
function returns.
*
ns->nids_state==NIDS_DATA
In this case, new data has arrived. Structures half_stream
(members of tcp_stream) contain buffers with data.
* The following values of nids_state field :
+ NIDS_CLOSE
+ NIDS_RESET
+ NIDS_TIMED_OUT
mean that the connection has been closed. Tcp_callback should free
allocated resources, if any.
*
ns->nids_state==NIDS_EXITING
In this case, libnids is exiting. This is the applications last
opportunity to make use of any data left stored in the half_stream
buffers. When reading traffic from a capture file rather than the
network, libnids may never see a close, reset, or timeout. If the
application has unprocessed data (e.g., from using nids_discard(),
this allows the application to process it.
4. A sample application
Now let's have a look at a simple application, which displays on
stderr data exchanged in all TCP connections seen by libnids.
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include "nids.h"
#define int_ntoa(x) inet_ntoa(*((struct in_addr *)&x))
// struct tuple4 contains addresses and port numbers of the TCP connections
// the following auxiliary function produces a string looking like
// 10.0.0.1,1024,10.0.0.2,23
char *
adres (struct tuple4 addr)
{
static char buf[256];
strcpy (buf, int_ntoa (addr.saddr));
sprintf (buf + strlen (buf), ",%i,", addr.source);
strcat (buf, int_ntoa (addr.daddr));
sprintf (buf + strlen (buf), ",%i", addr.dest);
return buf;
}
void
tcp_callback (struct tcp_stream *a_tcp, void ** this_time_not_needed)
{
char buf[1024];
strcpy (buf, adres (a_tcp->addr)); // we put conn params into buf
if (a_tcp->nids_state == NIDS_JUST_EST)
{
// connection described by a_tcp is established
// here we decide, if we wish to follow this stream
// sample condition: if (a_tcp->addr.dest!=23) return;
// in this simple app we follow each stream, so..
a_tcp->client.collect++; // we want data received by a client
a_tcp->server.collect++; // and by a server, too
a_tcp->server.collect_urg++; // we want urgent data received by a
// server
#ifdef WE_WANT_URGENT_DATA_RECEIVED_BY_A_CLIENT
a_tcp->client.collect_urg++; // if we don't increase this value,
// we won't be notified of urgent data
// arrival
#endif
fprintf (stderr, "%s established\n", buf);
return;
}
if (a_tcp->nids_state == NIDS_CLOSE)
{
// connection has been closed normally
fprintf (stderr, "%s closing\n", buf);
return;
}
if (a_tcp->nids_state == NIDS_RESET)
{
// connection has been closed by RST
fprintf (stderr, "%s reset\n", buf);
return;
}
if (a_tcp->nids_state == NIDS_DATA)
{
// new data has arrived; gotta determine in what direction
// and if it's urgent or not
struct half_stream *hlf;
if (a_tcp->server.count_new_urg)
{
// new byte of urgent data has arrived
strcat(buf,"(urgent->)");
buf[strlen(buf)+1]=0;
buf[strlen(buf)]=a_tcp->server.urgdata;
write(1,buf,strlen(buf));
return;
}
// We don't have to check if urgent data to client has arrived,
// because we haven't increased a_tcp->client.collect_urg variable.
// So, we have some normal data to take care of.
if (a_tcp->client.count_new)
{
// new data for the client
hlf = &a_tcp->client; // from now on, we will deal with hlf var,
// which will point to client side of conn
strcat (buf, "(<-)"); // symbolic direction of data
}
else
{
hlf = &a_tcp->server; // analogical
strcat (buf, "(->)");
}
fprintf(stderr,"%s",buf); // we print the connection parameters
// (saddr, daddr, sport, dport) accompanied
// by data flow direction (-> or <-)
write(2,hlf->data,hlf->count_new); // we print the newly arrived data
}
return ;
}
int
main ()
{
// here we can alter libnids params, for instance:
// nids_params.n_hosts=256;
if (!nids_init ())
{
fprintf(stderr,"%s\n",nids_errbuf);
exit(1);
}
nids_register_tcp (tcp_callback);
nids_run ();
return 0;
}
5. Basic libnids structures and functions
Now it's time for more systematic description of libnids structures.
As mentioned, they're all declared in nids.h
struct tuple4 // TCP connection parameters
没有合适的资源?快使用搜索试试~ 我知道了~
libnids 源码解读加了大量的注释
共65个文件
c:15个
h:7个
in:5个
4星 · 超过85%的资源 需积分: 35 200 下载量 53 浏览量
2009-11-19
10:33:29
上传
评论 2
收藏 245KB RAR 举报
温馨提示
libnids 源码解读,加了大量的注释,尤其是IP,TCP重组模块
资源推荐
资源详情
资源评论
收起资源包目录
libnids-1.20(自己注释过).rar (65个子文件)
libnids-1.20(自己注释过)
COPYING 18KB
mkinstalldirs 649B
configure 143KB
install-sh 5KB
Makefile.in 428B
configure.in 6KB
src
util.c 630B
tcp.h 489B
tcp.ncb 57KB
test.cpp 2KB
util.h 622B
hash.h 68B
allpromisc.c 1KB
ip_fragment.dsp 3KB
libnids.3.mdoc 11KB
ip_options.c 6KB
config.h.in 1KB
tcp.plg 851B
tcpstream.cpp 0B
ip_fragment.c 23KB
scan.h 454B
hash.c 1KB
checksum.h 278B
ip_fragment.ncb 323KB
ip_fragment.dsw 547B
Makefile.in 3KB
libnids.c 14KB
checksum.c 7KB
Debug
vc60.pdb 44KB
test.obj 2KB
killtcp.c 3KB
tcp.c 27KB
tcp.opt 55KB
nids.h 6KB
ip_fragment.h 348B
scan.c 3KB
libnids.3 11KB
ip_fragment.plg 1KB
ip_fragment.opt 53KB
MISC 3KB
config.guess 38KB
README 3KB
CREDITS 4KB
config.sub 27KB
CHANGES 5KB
doc
NEW_LIBPCAP 199B
PATCH 867B
bugtraq_post 4KB
LINUX 1KB
PERFORMANCE 3KB
API.html 26KB
TESTS 5KB
API.txt 23KB
samples
nids_next.c 907B
overflows.dsp 3KB
overflows.plg 899B
overflows.dsw 543B
overflows.c 6KB
overflows.ncb 33KB
Makefile.in 752B
Debug
vc60.pdb 28KB
printall.c 4KB
overflows.opt 48KB
chksum_ctl.c 2KB
sniff.c 2KB
共 65 条
- 1
车进
- 粉丝: 16
- 资源: 16
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
- 3
- 4
前往页