Transcript 投影片 1

Linux Netfilter Code Trace
Part1: Iptable
周世中 嚴長青
2002/7/31
1
Outline
•
•
•
•
Introduction
Data structure of iptable
How to check whether packets match rules
Reference
2002/7/31
2
Outline
•
•
•
•
Introduction
Data structure of iptable
How to check whether packets match rules
Reference
2002/7/31
3
Introduction
• Netfilter is a framework.
Port
forwarding
masquerading
Packet
filtering
2002/7/31
Transparent
proxy
4
Introduction
• A packet filtering system called IP Tables
has been built over the netfilter framework.
• IP Tables looks at the header of packets
as they pass through, and decides the fate
of the entire packet.
2002/7/31
5
Outline
•
•
•
•
Introduction
Data structure of iptable
How to check whether packets match rules
Reference
2002/7/31
6
Data Structure
• Each rule consists of the following parts:
– A “ sturct ipt_entry “ structure.
– 0 or more “ struct ipt_entry_match”
structures
– A “struct ipt_entry_target “ structure
…
ipt_entry
ipt_entry_target
ipt_entry_match
2002/7/31
7
Date Structure
• Example : Ping of death
# iptables -A FORWARD -p icmp --icmp-type echo-request
-m limit --limit 1/s -j ACCEPT
ipt_entry
ipt_entry_target
ipt_entry_match
2002/7/31
8
sturct ipt_entry
struct ipt_entry
{
struct ipt_ip ip;
unsigned int nfcache; /* Mark with fields that we care about. */
u_int16_t target_offset; /* Size of ipt_entry + matches */
u_int16_t next_offset; /* Size of ipt_entry + matches +
target */
unsigned int comefrom;
/* Back pointer */
struct ipt_counters counters;/* Packet and byte counters. */
unsigned char elems[0]; /* The matches (if any), then the
target. */
};
2002/7/31
/usr/src/linux-2.4.18/include/linux/netfilter_ipv4/ip_tables.h
9
2002/7/31
10
sturct ipt_ip
struct ipt_ip
{
struct in_addr src , dst; /* Source and destination IP addr */
struct in_addr smsk , dmsk; /* Mask for src and dest IP
addr */
char iniface[IFNAMSIZ] , outiface[IFNAMSIZ];
unsigned char iniface_mask[IFNAMSIZ] ,
outiface_mask[IFNAMSIZ];
u_int16_t proto;
/* Protocol, 0 = ANY */
u_int8_t flags;
/* Flags word */
u_int8_t invflags;
/* Inverse flags */
};
2002/7/31
/usr/src/linux-2.4.18/include/linux/netfilter_ipv4/ip_tables.h
11
sturct ipt_counters
struct ipt_counters
{
/* Packet and byte counters */
u_int64_t pcnt, bcnt;
};
2002/7/31
/usr/src/linux-2.4.18/include/linux/netfilter_ipv4/ip_tables.h
12
sturct ipt_entry_match
struct ipt_entry_match
{
union {
Used by userspace
struct {
u_int16_t match_size;
char name[IPT_FUNCTION_MAXNAMELEN];
} user;
struct {
Used inside the kernel
u_int16_t match_size;
struct ipt_match *match;
} kernel;
u_int16_t match_size; /* Total length */
} u;
unsigned char data[0];
};
2002/7/31
/usr/src/linux-2.4.18/include/linux/netfilter_ipv4/ip_tables.h
13
sturct ipt_match
 struct ipt_match
{
the name of the match function
struct list_head list;
a pointer to a match
const char name[IPT_FUNCTION_MAXNAMELEN];
function
/* Return true or false: return FALSE and set *hotdrop
= 1 to
force immediate packet drop. */
a pointer to a function which checks
int (*match) (…*skb, *in *out device,*matchinfo,offset,*hotdrop…);
specifications
for a rule
/* Called when user tries to insert an the
entry
of this type*/
int (*checkentry)(…*tablename,*ip,*matchinfo…);
a pointer to a function which is called when
/* Called when entry of this type deleted. */
an entry using this match is deleted
void (*destroy)(void *matchinfo, unsigned int matchinfosize);
/* Set this to THIS_MODULE if you are a module, otherwise
NULL */
gives a pointer to my module
struct module *me;
};
2002/7/31
/usr/src/linux-2.4.18/include/linux/netfilter_ipv4/ip_tables.h
14
ipt_entry
ipt_entry_target
ipt_match *match
ipt_match
ipt_match
return unsigned int
ipt_match
ipt_match
The match function
ipt_entry_match
2002/7/31
15
sturct ipt_entry_target
struct ipt_entry_target
{
union {
Used by userspace
struct {
u_int16_t target_size;
char name[IPT_FUNCTION_MAXNAMELEN];
} user;
struct {
Used inside the kernel
u_int16_t target_size;
struct ipt_target *target;
} kernel;
u_int16_t target_size; /* Total length */
} u;
unsigned char data[0];
};
2002/7/31
/usr/src/linux-2.4.18/include/linux/netfilter_ipv4/ip_tables.h
16
sturct ipt_target
struct ipt_target
the name of the target function a
{
struct list_head list;
a pointer to a target function
const char name[IPT_FUNCTION_MAXNAMELEN];
/* Returns verdict. */
unsigned int (*target)(…**pskb,hooknum,*in
a pointer to a *out
function which checks
device,*targinfo…);
the specifications for a rule
/* Called when user tries to insert an entry of this type:
hook_mask is a bitmask of hooks from which it can be called.
a pointer to a function which is called when
*/
entry using
this target is deleted
int (*checkentry)(…*tablename,an
ipt_entry
*e,*targinfo…);
/* Called when entry of this type deleted. */
void (*destroy)(void *targinfo, unsigned int targinfosize);
gives
a pointer to
my module
/* Set this to THIS_MODULE if you are
a module,
otherwise
NULL */
struct module *me;
};
2002/7/31
/usr/src/linux-2.4.18/include/linux/netfilter_ipv4/ip_tables.h
17
ipt_entry
ipt_entry_target
ipt_target *target
ipt_target
ipt_target
ipt_target
ipt_taeget
return 0 or a packet verdict
The target function
ipt_entry_match
2002/7/31
18
sturct ipt_standard_target
struct ipt_standard_target
{
struct ipt_entry_target target;
int verdict; /* the packet’s fate */
};
• There are two types of verdict of standard target
– NF_DROP , NF_ACCEPT , NF_QUEUE and
NF_STOLEN
– goto another user-defined chain of this table
2002/7/31
/usr/src/linux-2.4.18/net/ipv4/netfilter/ip_tables.c
19
sturct ipt_tcp
struct ipt_tcp
{
u_int16_t spts[2];
u_int16_t dpts[2];
u_int8_t option;
u_int8_t flg_mask;
u_int8_t flg_cmp;
u_int8_t invflags;
};
2002/7/31
/* Source port range. */
/* Destination port range. */
/* TCP Option iff non-zero*/
/* TCP flags mask byte */
/* TCP flags compare byte */
/* Inverse flags */
/usr/src/linux-2.4.18/include/linux/netfilter_ipv4/ip_tables.h
20
sturct ipt_udp
struct ipt_udp
{
u_int16_t spts[2];
u_int16_t dpts[2];
u_int8_t invflags;
};
2002/7/31
/* Source port range. */
/* Destination port range. */
/* Inverse flags */
/usr/src/linux-2.4.18/include/linux/netfilter_ipv4/ip_tables.h
21
sturct ipt_icmp
struct ipt_icmp
{
u_int8_t type
u_int8_t code[2]
u_int8_t invflags;
};
2002/7/31
/* type to match */
/* range of code */
/* Inverse flags */
/usr/src/linux-2.4.18/include/linux/netfilter_ipv4/ip_tables.h
22
Outline
•
•
•
•
Introduction
Data structure of iptable
How to check whether packets match rules
Reference
2002/7/31
23
How to check whether packets
match rules
• Check IP header
• Check matches
ipt_entry
ipt_ip
…
ipt_match
ipt_entry_match
• target
2002/7/31
ipt_entry_target
ipt_target
24
Check IP header
No match
Go to user-defined chain
No match
Check extension matches
Check if it’s target is standard
Decide the packet’s fate according to the target
2002/7/31
25
How to check whether packets
match rules
• ipt_do_table()
– All above are done in this function
– /usr/src/linux-2.4.18/net/ipv4/netfilter/ip_tables.c
2002/7/31
26
Parameters of ipt_do_table()
unsigned int ipt_do_table(
struct sk_buff **pskb, // pointer to sk_buff
usigned int hook, // hook number
const struct net_device *in, //specify in-interface
const struct net_device *out, //out-interface
struct ipt_table *table, //specify table
void *userdata
)
2002/7/31
27
Local variables of ipt_do_table()
struct iphdr *ip ; //pointer to packet ip header
struct ipt_entry *e; //pointer to the checking rule
Struct ipt_entry *back; //return point
2002/7/31
28
Return value of ipt_do_table()
• #define NF_DROP 0
NF_ACCEPT 1
NF_STOLEN 2
NF_QUEUE 3
NF_REPEAT 4
• /usr/src/linux-2.4.18/include/linux/netfilter.h
2002/7/31
29
Check IP header
No match
Go to user-defined chain
No match
Check extension matches
Check if it’s target is standard
Decide the packet’s fate according to the target
2002/7/31
30
ipt_entry
ipt_entry_target
ipt_entry_match
2002/7/31
31
Check IP header
• ip_packet_match() is used to check IP header
• Actually each element of the struct ipt_ip,
including in-interface,out-interface and IP
header,is checked here
• All this function do is to check “basic” part of
matches.
• /usr/src/linux-2.4.18/net/ipv4/netfilter/ip_tables.c
2002/7/31
32
Check IP header
static inline int ip_packet_match (
const struct iphdr *ip, //pointer to packet ip header
const char *indev, //in-interface of the packet
const char *outdev, //out-interface of the packet
const struct ipt_ip *ipinfo, //the basic macthes
int isfrag //fragment offset
)
2002/7/31
33
Check IP header
• In ip_packet_match(),the macro FWINV is
used to complete the main matches
• #define FWINV (bool,invflg)
((bool) ^ !!(ipinfo->invflags & invflg))
– Evaluated true means mismatch
• Ex.
– FWINV((ip->saddr & ipinfo-> smsk.s_addr) != ipinfo->
src.s_addr, IPT_INV_SRCIP)
2002/7/31
34
Check IP header
• Return value of ip_packet_match()
– 0 means mismatch
– 1 means match
2002/7/31
35
Check IP header
No match
Go to user-defined chain
No match
Check extension matches
Check if it’s target is standard
Decide the packet’s fate according to the target
2002/7/31
36
IP header no match
• e = (void *)e+ e->next_offset;
– This rule is mismatch,so the next rule is
examined
2002/7/31
37
Check IP header
No match
Go to user-defined chain
No match
Check extension matches
Check if it’s target is standard
Decide the packet’s fate according to the target
2002/7/31
38
Check extension match
• If the “basic” part is matched, then the
extension matches are examined.
2002/7/31
39
ipt_entry
ipt_entry_target
ipt_entry_match
2002/7/31
40
Check extension match
IPT_MATCH_ITERATE
do_match()
match function of the match
2002/7/31
41
ipt_entry
ipt_entry_target
ipt_match *match
ipt_match
ipt_match
return unsigned int
ipt_match
ipt_match
The match function
ipt_entry_match
2002/7/31
42
Check extension match
• IPT_MATCH_ITERATE
– The macro is a for-loop in order to examine if each
match of this rule matches iteratedly
– For(i= size of ipt_entry;i<target_offset;i+=size of this
match){
ret=do_match(this match…)
if(ret!=0)
break;
} ret;
• /usr/src/linux-2.4.18/include/linux/netfilter_ipv4/ip_tables.h
2002/7/31
43
Check extension match
• do_match()
– If(match function of the match succeed )
return 0;
else
return 1;
– /usr/src/linux-2.4.18/net/ipv4/netfilter/ip_tables.c
2002/7/31
44
Check IP header
No match
Go to user-defined chain
No match
Check extension matches
Check if it’s target is standard
Decide the packet’s fate according to the target
2002/7/31
45
Check extension no match
• e = (void *)e+ e->next_offset;
– This rule is mismatch,so the next rule is
examined
2002/7/31
46
Check IP header
No match
Go to user-defined chain
No match
Check extension matches
Check if it’s target is standard
Decide the packet’s fate according to the target
2002/7/31
47
Increase Counter
• ADD_COUNTER(e->counters, ntohs(ip ->
tot_len),1);
• /usr/src/linux-2.4.18/net/ipv4/netfilter/ip_tables.c
2002/7/31
48
Check if it’s target is standard
• If(target function of the target not exist)
standard target;
else
nonstandard target;
2002/7/31
49
ipt_entry
ipt_entry_target
ipt_target *target
ipt_target
ipt_target
ipt_target
ipt_taeget
return 0 or a packet verdict
The target function
ipt_entry_match
2002/7/31
50
Check if it’s target is standard
• Standard target
– The following standard targets are supported:
• ACCEPT, DROP, QUEUE, RETURN, and JUMP
(which is translated from the chain name to an
actual offset within the table).
• Nonstandard target
2002/7/31
51
Check IP header
No match
Go to user-defined chain
No match
Check extension matches
Check if it’s target is standard
Decide the packet’s fate according to the target
2002/7/31
52
Decide the packet’s fate
• Standard target
– Struct ipt_standard_target{
struct ipt_entry_target;
int verdict; // the packet’s fate
}
• /usr/src/linux-2.4.18/net/ipv4/netfilter/iptable_filter.c
2002/7/31
53
ipt_entry
ipt_standard_target
ipt_entry_match
2002/7/31
54
Decide the packet’s fate
• Standard target
– If(verdict<0)
verdict=(unsigned)(-verdict)-1;
// one of NF_DROP , NF_ACCEPT ,
//NF_QUEUE and NF_STOLEN
else
e=get_entry(table_base,verdict);
// goto another user-defined chain of this
table
2002/7/31
55
Decide the packet’s fate
Static inline struct ipt_entry*
get_entry(void *base, unsigned int offset){
return(struct ipt_entry *)(base+offset);
}
• /usr/src/linux-2.4.18/net/ipv4/netfilter/ip_tables.c
2002/7/31
56
Check IP header
No match
Go to user-defined chain
No match
Check extension matches
Check if it’s target is standard
Decide the packet’s fate according to the target
2002/7/31
57
Decide the packet’s fate
• Nonstandard target
– The target function will be called
– The packet’s fate,verdict,is the return value of
the target function
2002/7/31
58
ipt_entry
ipt_entry_target
ipt_target *target
ipt_target
ipt_target
ipt_target
ipt_taeget
return 0 or a packet verdict
The target function
ipt_entry_match
2002/7/31
59
Decide the packet’s fate
• Finally,the variable “verdict” will be
returned.
• If the value of “verdict” is IPT_CONTINUE,
the packet will be checked with the next
rule
2002/7/31
60
Reference
• netfilter-hacking-HOWTO
• Packet-filtering-HOWTO
• http://lxr.linux.no
2002/7/31
61