Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Arne Øslebø
mapi
Commits
f16eab13
Commit
f16eab13
authored
Oct 20, 2005
by
Browse files
fixes in libnids
git-svn-id:
file:///home/svn/mapi/trunk@220
8d5bb341-7cf1-0310-8cf6-ba355fef3186
parent
f530671e
Changes
7
Hide whitespace changes
Inline
Side-by-side
stdlib/cooking.c
View file @
f16eab13
...
...
@@ -34,23 +34,16 @@ static int threshold = 0;
static
unsigned
int
timeout
=
0
;
//unsigned int client_size = 0,server_size=0;
struct
mapidlibflow
*
mod_flow
=
NULL
;
char
*
to_free
=
NULL
;
char
*
to_free2
=
NULL
;
struct
headers_data
*
headers
=
NULL
;
extern
struct
pcap_pkthdr
*
nids_last_pcap_header
;
mapid_pkthdr_t
*
last_mapid_header
;
int
status
;
unsigned
char
*
last_dev_pkt
;
struct
mapidlibflow
*
cook_tmp_flow
=
NULL
;
static
int
cooking_id
=
0
;
extern
struct
tcp_stream
*
find_stream
(
struct
tcphdr
*
this_tcphdr
,
struct
ip
*
this_iphdr
,
int
*
from_client
,
int
id
);
void
create_mod_pkt
(
unsigned
char
*
dev_pkt
,
struct
mapidlibflow
*
flow
,
mapid_pkthdr_t
*
pkt_head
);
void
process_flushed_data
(
struct
mapidlibflow
*
flow
);
static
int
cook_instance
(
mapidflib_function_instance_t
*
instance
,
flist_t
*
flist
,
mapidflib_flow_mod_t
*
flow_mod
,
function_manipulation_t
*
manip
)
{
...
...
@@ -145,7 +138,6 @@ void tcp_callback(struct tcp_stream *ns, void **param)
ns
->
client
.
read
=
0
;
ns
->
client
.
total_read
=
0
;
if
(
ns
->
client
.
headers
==
NULL
)
{
fprintf
(
stderr
,
"Initing 2..
\n
"
);
ns
->
client
.
headers
=
(
flist_t
*
)
malloc
(
sizeof
(
flist_t
));
flist_init
(
ns
->
client
.
headers
);
}
...
...
@@ -346,8 +338,7 @@ void tcp_callback(struct tcp_stream *ns, void **param)
return
;
}
static
int
cook_init
(
mapidflib_function_instance_t
*
instance
,
flist_t
*
flist
)
static
int
cook_init
(
mapidflib_function_instance_t
*
instance
,
flist_t
*
flist
)
{
mapiFunctArg
*
fargs
;
struct
pcap
desc
;
...
...
@@ -365,6 +356,7 @@ static int cook_init(mapidflib_function_instance_t *instance,
desc
.
linktype
=
instance
->
hwinfo
->
link_type
;
desc
.
bufsize
=
instance
->
hwinfo
->
cap_length
;
printf
(
"INiting::: %d
\n
"
,
data
->
id
);
nids_mapi_init
(
&
desc
,
instance
->
hwinfo
->
link_type
,
data
->
id
);
nids_mapi_register_tcp
(
tcp_callback
,
data
->
id
);
...
...
@@ -382,7 +374,7 @@ static int cook_init(mapidflib_function_instance_t *instance,
// return 1 in order for processing to continue in other functions
// return 0 not to
static
int
cook_process
(
mapidflib_function_instance_t
*
instance
,
const
unsigned
char
*
dev_pkt
,
const
unsigned
char
*
link_pkt
,
mapid_pkthdr_t
*
pkt_head
)
static
int
cook_process
(
mapidflib_function_instance_t
*
instance
,
const
unsigned
char
*
dev_pkt
,
unsigned
char
*
link_pkt
,
mapid_pkthdr_t
*
pkt_head
)
{
struct
pcap_pkthdr
h
;
...
...
@@ -391,21 +383,23 @@ static int cook_process(mapidflib_function_instance_t *instance,const unsigned c
struct
tcphdr
*
tcph
;
int
ether_len
=
0
,
ip_len
=
0
;
struct
mapidlibflow
*
flow
;
struct
cooking_data
*
data
;
struct
headers_data
*
headers
;
data
=
(
struct
cooking_data
*
)(
instance
->
internal_data
);
threshold
=
data
->
threshold
;
timeout
=
data
->
timeout
;
flow
=
data
->
flow
;
//fprintf(stderr,"I am COOKING\n");
last_dev_pkt
=
link_pkt
;
last_mapid_header
=
pkt_head
;
h
.
caplen
=
pkt_head
->
caplen
;
h
.
len
=
pkt_head
->
wlen
;
h
.
ts
.
tv_sec
=
pkt_head
->
ts
;
//XXX
h
.
ts
.
tv_usec
=
pkt_head
->
ts
;
struct
cooking_data
*
data
=
(
struct
cooking_data
*
)(
instance
->
internal_data
);
threshold
=
data
->
threshold
;
timeout
=
data
->
timeout
;
flow
=
data
->
flow
;
status
=
NON_CHECKED
;
...
...
@@ -413,7 +407,6 @@ static int cook_process(mapidflib_function_instance_t *instance,const unsigned c
flow
->
ret_server_data
=
NULL
;
flow
->
client_size
=
flow
->
server_size
=
0
;
eth
=
(
ether_header
*
)
link_pkt
;
ether_len
=
sizeof
(
ether_header
);
iph
=
(
struct
ip
*
)(
link_pkt
+
ether_len
);
...
...
@@ -431,7 +424,6 @@ static int cook_process(mapidflib_function_instance_t *instance,const unsigned c
tcph
=
(
struct
tcphdr
*
)(
link_pkt
+
ether_len
+
ip_len
);
//XXX replace 0
stream
=
find_stream
(
tcph
,
iph
,
&
from_client
,
data
->
id
);
if
(
stream
)
{
//fprintf(stderr,"\tStream found\n");
...
...
@@ -480,7 +472,6 @@ static int cook_process(mapidflib_function_instance_t *instance,const unsigned c
headers
->
ts
.
tv_sec
=
pkt_head
->
ts
;
//XXX
headers
->
ts
.
tv_usec
=
pkt_head
->
ts
;
//XXX replace 0
stream
=
find_stream
(
tcph
,
iph
,
&
from_client
,
data
->
id
);
if
(
stream
==
NULL
)
{
//fprintf(stderr,"\tNULL stream %d %d\n",headers->ts.tv_sec,headers->ts.tv_usec);
...
...
stdlib/libnids/ip_fragment.c
View file @
f16eab13
...
...
@@ -95,13 +95,13 @@ struct ipq {
This fragment handler is a bit of a heap. On the other hand it works
quite happily and handles things quite well.
*/
static
struct
hostfrags
**
fragtable
;
static
struct
hostfrags
*
this_host
;
static
struct
hostfrags
**
fragtable
[
MAX_LIBNIDS_INSTANCES
]
;
static
struct
hostfrags
*
this_host
[
MAX_LIBNIDS_INSTANCES
]
;
static
int
numpack
=
0
;
static
int
hash_size
;
static
int
timenow
;
static
unsigned
int
time0
;
static
struct
timer_list
*
timer_head
=
0
,
*
timer_tail
=
0
;
static
struct
timer_list
*
timer_head
[
MAX_LIBNIDS_INSTANCES
],
*
timer_tail
[
MAX_LIBNIDS_INSTANCES
]
;
#define int_ntoa(x) inet_ntoa(*((struct in_addr *)&x))
...
...
@@ -146,69 +146,69 @@ panic(char *str)
}
static
void
add_timer
(
struct
timer_list
*
x
)
add_timer
(
struct
timer_list
*
x
,
int
id
)
{
if
(
timer_tail
)
{
timer_tail
->
next
=
x
;
x
->
prev
=
timer_tail
;
if
(
timer_tail
[
id
]
)
{
timer_tail
[
id
]
->
next
=
x
;
x
->
prev
=
timer_tail
[
id
]
;
x
->
next
=
0
;
timer_tail
=
x
;
timer_tail
[
id
]
=
x
;
}
else
{
x
->
prev
=
0
;
x
->
next
=
0
;
timer_tail
=
timer_head
=
x
;
timer_tail
[
id
]
=
timer_head
[
id
]
=
x
;
}
}
static
void
del_timer
(
struct
timer_list
*
x
)
del_timer
(
struct
timer_list
*
x
,
int
id
)
{
if
(
x
->
prev
)
x
->
prev
->
next
=
x
->
next
;
else
timer_head
=
x
->
next
;
timer_head
[
id
]
=
x
->
next
;
if
(
x
->
next
)
x
->
next
->
prev
=
x
->
prev
;
else
timer_tail
=
x
->
prev
;
timer_tail
[
id
]
=
x
->
prev
;
}
static
void
frag_kfree_skb
(
struct
sk_buff
*
skb
,
int
type
)
frag_kfree_skb
(
struct
sk_buff
*
skb
,
int
type
,
int
id
)
{
if
(
this_host
)
atomic_sub
(
skb
->
truesize
,
&
this_host
->
ip_frag_mem
);
if
(
this_host
[
id
]
)
atomic_sub
(
skb
->
truesize
,
&
this_host
[
id
]
->
ip_frag_mem
);
kfree_skb
(
skb
,
type
);
}
static
void
frag_kfree_s
(
void
*
ptr
,
int
len
)
frag_kfree_s
(
void
*
ptr
,
int
len
,
int
id
)
{
if
(
this_host
)
atomic_sub
(
len
,
&
this_host
->
ip_frag_mem
);
if
(
this_host
[
id
]
)
atomic_sub
(
len
,
&
this_host
[
id
]
->
ip_frag_mem
);
free
(
ptr
);
}
static
void
*
frag_kmalloc
(
int
size
,
int
dummy
)
frag_kmalloc
(
int
size
,
int
dummy
,
int
id
)
{
void
*
vp
=
(
void
*
)
malloc
(
size
);
(
void
)
dummy
;
if
(
!
vp
)
return
NULL
;
atomic_add
(
size
,
&
this_host
->
ip_frag_mem
);
atomic_add
(
size
,
&
this_host
[
id
]
->
ip_frag_mem
);
return
vp
;
}
/* Create a new fragment entry. */
static
struct
ipfrag
*
ip_frag_create
(
int
offset
,
int
end
,
struct
sk_buff
*
skb
,
unsigned
char
*
ptr
)
ip_frag_create
(
int
offset
,
int
end
,
struct
sk_buff
*
skb
,
unsigned
char
*
ptr
,
int
id
)
{
struct
ipfrag
*
fp
;
fp
=
(
struct
ipfrag
*
)
frag_kmalloc
(
sizeof
(
struct
ipfrag
),
GFP_ATOMIC
);
fp
=
(
struct
ipfrag
*
)
frag_kmalloc
(
sizeof
(
struct
ipfrag
),
GFP_ATOMIC
,
id
);
if
(
fp
==
NULL
)
{
// NETDEBUG(printk("IP: frag_create: no memory left !\n"));
nids_params
.
no_mem
(
"ip_frag_create"
);
...
...
@@ -224,7 +224,7 @@ ip_frag_create(int offset, int end, struct sk_buff * skb, unsigned char *ptr)
fp
->
ptr
=
ptr
;
/* Charge for the SKB as well. */
this_host
->
ip_frag_mem
+=
skb
->
truesize
;
this_host
[
id
]
->
ip_frag_mem
+=
skb
->
truesize
;
return
(
fp
);
}
...
...
@@ -238,59 +238,59 @@ frag_index(struct ip * iph)
}
static
int
hostfrag_find
(
struct
ip
*
iph
)
hostfrag_find
(
struct
ip
*
iph
,
int
id
)
{
int
hash_index
=
frag_index
(
iph
);
struct
hostfrags
*
hf
;
this_host
=
0
;
for
(
hf
=
fragtable
[
hash_index
];
hf
;
hf
=
hf
->
next
)
{
this_host
[
id
]
=
0
;
for
(
hf
=
fragtable
[
id
][
hash_index
];
hf
;
hf
=
hf
->
next
)
{
if
(
hf
->
ip
==
iph
->
ip_dst
.
s_addr
)
{
this_host
=
hf
;
this_host
[
id
]
=
hf
;
break
;
}
}
if
(
!
this_host
)
if
(
!
this_host
[
id
]
)
return
0
;
else
return
1
;
}
static
void
hostfrag_create
(
struct
ip
*
iph
)
hostfrag_create
(
struct
ip
*
iph
,
int
id
)
{
struct
hostfrags
*
hf
=
mknew
(
struct
hostfrags
);
int
hash_index
=
frag_index
(
iph
);
hf
->
prev
=
0
;
hf
->
next
=
fragtable
[
hash_index
];
hf
->
next
=
fragtable
[
id
][
hash_index
];
if
(
hf
->
next
)
hf
->
next
->
prev
=
hf
;
fragtable
[
hash_index
]
=
hf
;
fragtable
[
id
][
hash_index
]
=
hf
;
hf
->
ip
=
iph
->
ip_dst
.
s_addr
;
hf
->
ipqueue
=
0
;
hf
->
ip_frag_mem
=
0
;
hf
->
hash_index
=
hash_index
;
this_host
=
hf
;
this_host
[
id
]
=
hf
;
}
static
void
rmthis_host
()
rmthis_host
(
int
id
)
{
int
hash_index
=
this_host
->
hash_index
;
int
hash_index
=
this_host
[
id
]
->
hash_index
;
if
(
this_host
->
prev
)
{
this_host
->
prev
->
next
=
this_host
->
next
;
if
(
this_host
->
next
)
this_host
->
next
->
prev
=
this_host
->
prev
;
if
(
this_host
[
id
]
->
prev
)
{
this_host
[
id
]
->
prev
->
next
=
this_host
[
id
]
->
next
;
if
(
this_host
[
id
]
->
next
)
this_host
[
id
]
->
next
->
prev
=
this_host
[
id
]
->
prev
;
}
else
{
fragtable
[
hash_index
]
=
this_host
->
next
;
if
(
this_host
->
next
)
this_host
->
next
->
prev
=
0
;
fragtable
[
id
][
hash_index
]
=
this_host
[
id
]
->
next
;
if
(
this_host
[
id
]
->
next
)
this_host
[
id
]
->
next
->
prev
=
0
;
}
free
(
this_host
);
this_host
=
0
;
free
(
this_host
[
id
]
);
this_host
[
id
]
=
0
;
}
/*
...
...
@@ -298,18 +298,18 @@ rmthis_host()
IP datagram, and return the queue entry address if found.
*/
static
struct
ipq
*
ip_find
(
struct
ip
*
iph
)
ip_find
(
struct
ip
*
iph
,
int
id
)
{
struct
ipq
*
qp
;
struct
ipq
*
qplast
;
qplast
=
NULL
;
for
(
qp
=
this_host
->
ipqueue
;
qp
!=
NULL
;
qplast
=
qp
,
qp
=
qp
->
next
)
{
for
(
qp
=
this_host
[
id
]
->
ipqueue
;
qp
!=
NULL
;
qplast
=
qp
,
qp
=
qp
->
next
)
{
if
(
iph
->
ip_id
==
qp
->
iph
->
ip_id
&&
iph
->
ip_src
.
s_addr
==
qp
->
iph
->
ip_src
.
s_addr
&&
iph
->
ip_dst
.
s_addr
==
qp
->
iph
->
ip_dst
.
s_addr
&&
iph
->
ip_p
==
qp
->
iph
->
ip_p
)
{
del_timer
(
&
qp
->
timer
);
/* So it doesn't vanish on us. The timer will
del_timer
(
&
qp
->
timer
,
id
);
/* So it doesn't vanish on us. The timer will
be reset anyway */
return
(
qp
);
}
...
...
@@ -323,21 +323,21 @@ ip_find(struct ip * iph)
timed out.
*/
static
void
ip_free
(
struct
ipq
*
qp
)
ip_free
(
struct
ipq
*
qp
,
int
id
)
{
struct
ipfrag
*
fp
;
struct
ipfrag
*
xp
;
/* Stop the timer for this entry. */
del_timer
(
&
qp
->
timer
);
del_timer
(
&
qp
->
timer
,
id
);
/* Remove this entry from the "incomplete datagrams" queue. */
if
(
qp
->
prev
==
NULL
)
{
this_host
->
ipqueue
=
qp
->
next
;
if
(
this_host
->
ipqueue
!=
NULL
)
this_host
->
ipqueue
->
prev
=
NULL
;
this_host
[
id
]
->
ipqueue
=
qp
->
next
;
if
(
this_host
[
id
]
->
ipqueue
!=
NULL
)
this_host
[
id
]
->
ipqueue
->
prev
=
NULL
;
else
rmthis_host
();
rmthis_host
(
id
);
}
else
{
qp
->
prev
->
next
=
qp
->
next
;
...
...
@@ -348,27 +348,27 @@ ip_free(struct ipq * qp)
fp
=
qp
->
fragments
;
while
(
fp
!=
NULL
)
{
xp
=
fp
->
next
;
frag_kfree_skb
(
fp
->
skb
,
FREE_READ
);
frag_kfree_s
(
fp
,
sizeof
(
struct
ipfrag
));
frag_kfree_skb
(
fp
->
skb
,
FREE_READ
,
id
);
frag_kfree_s
(
fp
,
sizeof
(
struct
ipfrag
)
,
id
);
fp
=
xp
;
}
/* Release the IP header. */
frag_kfree_s
(
qp
->
iph
,
64
+
8
);
frag_kfree_s
(
qp
->
iph
,
64
+
8
,
id
);
/* Finally, release the queue descriptor itself. */
frag_kfree_s
(
qp
,
sizeof
(
struct
ipq
));
frag_kfree_s
(
qp
,
sizeof
(
struct
ipq
)
,
id
);
}
/* Oops- a fragment queue timed out. Kill it and send an ICMP reply. */
static
void
ip_expire
(
unsigned
long
arg
)
ip_expire
(
unsigned
long
arg
,
int
id
)
{
struct
ipq
*
qp
;
qp
=
(
struct
ipq
*
)
arg
;
/* Nuke the fragment queue. */
ip_free
(
qp
);
ip_free
(
qp
,
id
);
}
/*
...
...
@@ -376,13 +376,13 @@ ip_expire(unsigned long arg)
queue until we are back under the low threshold.
*/
static
void
ip_evictor
(
vo
id
)
ip_evictor
(
int
id
)
{
// fprintf(stderr, "ip_evict:numpack=%i\n", numpack);
while
(
this_host
->
ip_frag_mem
>
IPFRAG_LOW_THRESH
)
{
if
(
!
this_host
->
ipqueue
)
while
(
this_host
[
id
]
->
ip_frag_mem
>
IPFRAG_LOW_THRESH
)
{
if
(
!
this_host
[
id
]
->
ipqueue
)
panic
(
"ip_evictor: memcount"
);
ip_free
(
this_host
->
ipqueue
);
ip_free
(
this_host
[
id
]
->
ipqueue
,
id
);
}
}
...
...
@@ -393,12 +393,12 @@ ip_evictor(void)
will insert the received fragments at their respective positions.
*/
static
struct
ipq
*
ip_create
(
struct
ip
*
iph
)
ip_create
(
struct
ip
*
iph
,
int
id
)
{
struct
ipq
*
qp
;
int
ihlen
;
qp
=
(
struct
ipq
*
)
frag_kmalloc
(
sizeof
(
struct
ipq
),
GFP_ATOMIC
);
qp
=
(
struct
ipq
*
)
frag_kmalloc
(
sizeof
(
struct
ipq
),
GFP_ATOMIC
,
id
);
if
(
qp
==
NULL
)
{
// NETDEBUG(printk("IP: create: no memory left !\n"));
nids_params
.
no_mem
(
"ip_create"
);
...
...
@@ -408,31 +408,31 @@ ip_create(struct ip * iph)
/* Allocate memory for the IP header (plus 8 octets for ICMP). */
ihlen
=
iph
->
ip_hl
*
4
;
qp
->
iph
=
(
struct
ip
*
)
frag_kmalloc
(
64
+
8
,
GFP_ATOMIC
);
qp
->
iph
=
(
struct
ip
*
)
frag_kmalloc
(
64
+
8
,
GFP_ATOMIC
,
id
);
if
(
qp
->
iph
==
NULL
)
{
//NETDEBUG(printk("IP: create: no memory left !\n"));
nids_params
.
no_mem
(
"ip_create"
);
frag_kfree_s
(
qp
,
sizeof
(
struct
ipq
));
frag_kfree_s
(
qp
,
sizeof
(
struct
ipq
)
,
id
);
return
(
NULL
);
}
memcpy
(
qp
->
iph
,
iph
,
ihlen
+
8
);
qp
->
len
=
0
;
qp
->
ihlen
=
ihlen
;
qp
->
fragments
=
NULL
;
qp
->
hf
=
this_host
;
qp
->
hf
=
this_host
[
id
]
;
/* Start a timer for this entry. */
qp
->
timer
.
expires
=
jiffies
()
+
IP_FRAG_TIME
;
/* about 30 seconds */
qp
->
timer
.
data
=
(
unsigned
long
)
qp
;
/* pointer to queue */
qp
->
timer
.
function
=
ip_expire
;
/* expire function */
add_timer
(
&
qp
->
timer
);
add_timer
(
&
qp
->
timer
,
id
);
/* Add this entry to the queue. */
qp
->
prev
=
NULL
;
qp
->
next
=
this_host
->
ipqueue
;
qp
->
next
=
this_host
[
id
]
->
ipqueue
;
if
(
qp
->
next
!=
NULL
)
qp
->
next
->
prev
=
qp
;
this_host
->
ipqueue
=
qp
;
this_host
[
id
]
->
ipqueue
=
qp
;
return
(
qp
);
}
...
...
@@ -470,7 +470,7 @@ ip_done(struct ipq * qp)
not going to touch this with a bargepole.
*/
static
char
*
ip_glue
(
struct
ipq
*
qp
)
ip_glue
(
struct
ipq
*
qp
,
int
id
)
{
char
*
skb
;
struct
ip
*
iph
;
...
...
@@ -484,13 +484,13 @@ ip_glue(struct ipq * qp)
if
(
len
>
65535
)
{
// NETDEBUG(printk("Oversized IP packet from %s.\n", int_ntoa(qp->iph->ip_src.s_addr)));
nids_params
.
syslog
(
NIDS_WARN_IP
,
NIDS_WARN_IP_OVERSIZED
,
qp
->
iph
,
0
);
ip_free
(
qp
);
ip_free
(
qp
,
id
);
return
NULL
;
}
if
((
skb
=
(
char
*
)
malloc
(
len
))
==
NULL
)
{
// NETDEBUG(printk("IP: queue_glue: no memory for gluing queue %p\n", qp));
nids_params
.
no_mem
(
"ip_glue"
);
ip_free
(
qp
);
ip_free
(
qp
,
id
);
return
(
NULL
);
}
/* Fill in the basic details. */
...
...
@@ -505,7 +505,7 @@ ip_glue(struct ipq * qp)
if
(
fp
->
len
<
0
||
fp
->
offset
+
qp
->
ihlen
+
fp
->
len
>
len
)
{
//NETDEBUG(printk("Invalid fragment list: Fragment over size.\n"));
nids_params
.
syslog
(
NIDS_WARN_IP
,
NIDS_WARN_IP_INVLIST
,
qp
->
iph
,
0
);
ip_free
(
qp
);
ip_free
(
qp
,
id
);
//kfree_skb(skb, FREE_WRITE);
//ip_statistics.IpReasmFails++;
free
(
skb
);
...
...
@@ -516,7 +516,7 @@ ip_glue(struct ipq * qp)
fp
=
fp
->
next
;
}
/* We glued together all fragments, so remove the queue entry. */
ip_free
(
qp
);
ip_free
(
qp
,
id
);
/* Done with all fragments. Fixup the new IP header. */
iph
=
(
struct
ip
*
)
skb
;
...
...
@@ -529,7 +529,7 @@ ip_glue(struct ipq * qp)
/* Process an incoming IP datagram fragment. */
static
char
*
ip_defrag
(
struct
ip
*
iph
,
struct
sk_buff
*
skb
)
ip_defrag
(
struct
ip
*
iph
,
struct
sk_buff
*
skb
,
int
id
)
{
struct
ipfrag
*
prev
,
*
next
,
*
tmp
;
struct
ipfrag
*
tfp
;
...
...
@@ -539,17 +539,17 @@ ip_defrag(struct ip *iph, struct sk_buff *skb)
int
flags
,
offset
;
int
i
,
ihl
,
end
;
if
(
!
hostfrag_find
(
iph
)
&&
skb
)
hostfrag_create
(
iph
);
if
(
!
hostfrag_find
(
iph
,
id
)
&&
skb
)
hostfrag_create
(
iph
,
id
);
/* Start by cleaning up the memory. */
if
(
this_host
)
if
(
this_host
->
ip_frag_mem
>
IPFRAG_HIGH_THRESH
)
ip_evictor
();
if
(
this_host
[
id
]
)
if
(
this_host
[
id
]
->
ip_frag_mem
>
IPFRAG_HIGH_THRESH
)
ip_evictor
(
id
);
/* Find the entry of this IP datagram in the "incomplete datagrams" queue. */
if
(
this_host
)
qp
=
ip_find
(
iph
);
if
(
this_host
[
id
]
)
qp
=
ip_find
(
iph
,
id
);
else
qp
=
0
;
...
...
@@ -559,7 +559,7 @@ ip_defrag(struct ip *iph, struct sk_buff *skb)
offset
&=
IP_OFFSET
;
if
(((
flags
&
IP_MF
)
==
0
)
&&
(
offset
==
0
))
{
if
(
qp
!=
NULL
)
ip_free
(
qp
);
/* Fragmented frame replaced by full
ip_free
(
qp
,
id
);
/* Fragmented frame replaced by full
unfragmented copy */
return
0
;
}
...
...
@@ -578,15 +578,15 @@ ip_defrag(struct ip *iph, struct sk_buff *skb)
qp
->
ihlen
=
ihl
;
memcpy
(
qp
->
iph
,
iph
,
ihl
+
8
);
}
del_timer
(
&
qp
->
timer
);
del_timer
(
&
qp
->
timer
,
id
);
qp
->
timer
.
expires
=
jiffies
()
+
IP_FRAG_TIME
;
/* about 30 seconds */
qp
->
timer
.
data
=
(
unsigned
long
)
qp
;
/* pointer to queue */
qp
->
timer
.
function
=
ip_expire
;
/* expire function */
add_timer
(
&
qp
->
timer
);
add_timer
(
&
qp
->
timer
,
id
);
}
else
{
/* If we failed to create it, then discard the frame. */
if
((
qp
=
ip_create
(
iph
))
==
NULL
)
{
if
((
qp
=
ip_create
(
iph
,
id
))
==
NULL
)
{
kfree_skb
(
skb
,
FREE_READ
);
return
NULL
;
}
...
...
@@ -660,13 +660,13 @@ ip_defrag(struct ip *iph, struct sk_buff *skb)
next
=
tfp
;
/* We have killed the original next frame */
frag_kfree_skb
(
tmp
->
skb
,
FREE_READ
);
frag_kfree_s
(
tmp
,
sizeof
(
struct
ipfrag
));
frag_kfree_skb
(
tmp
->
skb
,
FREE_READ
,
id
);
frag_kfree_s
(
tmp
,
sizeof
(
struct
ipfrag
)
,
id
);
}
}
/* Insert this fragment in the chain of fragments. */
tfp
=
NULL
;
tfp
=
ip_frag_create
(
offset
,
end
,
skb
,
ptr
);
tfp
=
ip_frag_create
(
offset
,
end
,
skb
,
ptr
,
id
);
/*
No memory to save the fragment - so throw the lot. If we failed
...
...
@@ -694,29 +694,29 @@ ip_defrag(struct ip *iph, struct sk_buff *skb)
layer...
*/
if
(
ip_done
(
qp
))
{
skb2
=
ip_glue
(
qp
);
/* glue together the fragments */
skb2
=
ip_glue
(
qp
,
id
);
/* glue together the fragments */
return
(
skb2
);
}
return
(
NULL
);
}
int
ip_defrag_stub
(
struct
ip
*
iph
,
struct
ip
**
defrag
)
ip_defrag_stub
(
struct
ip
*
iph
,
struct
ip
**
defrag
,
int
id
)
{
int
offset
,
flags
,
tot_len
;
struct
sk_buff
*
skb
;
numpack
++
;
timenow
=
0
;
while
(
timer_head
&&
timer_head
->
expires
<
jiffies
())
{
this_host
=
((
struct
ipq
*
)
(
timer_head
->
data
))
->
hf
;
timer_head
->
function
(
timer_head
->
data
);
while
(
timer_head
[
id
]
&&
timer_head
[
id
]
->
expires
<
jiffies
())
{
this_host
[
id
]
=
((
struct
ipq
*
)
(
timer_head
[
id
]
->
data
))
->
hf
;
timer_head
[
id
]
->
function
(
timer_head
[
id
]
->
data
);
}
offset
=
ntohs
(
iph
->
ip_off
);
flags
=
offset
&
~
IP_OFFSET
;
offset
&=
IP_OFFSET
;
if
(((
flags
&
IP_MF
)
==
0
)
&&
(
offset
==
0
))
{
ip_defrag
(
iph
,
0
);
ip_defrag
(
iph
,
0
,
id
);
return
IPF_NOTF
;
}
tot_len
=
ntohs
(
iph
->
ip_len