sch3m4 / libntoh Goto Github PK
View Code? Open in Web Editor NEWUser-friendly C Library to perform TCP streams reassembly and IPv4/6 defragmentation
Home Page: http://safetybits.net
License: Other
User-friendly C Library to perform TCP streams reassembly and IPv4/6 defragmentation
Home Page: http://safetybits.net
License: Other
if ( data->protocol == IPPROTO_IPV6 ) , len will be equal to ARRAY_SIZE, val[len] & val[(len*2)+1] will overflow
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
Hi,
The code in the Wiki pages needs review as some functions still use old signature
"ntoh_tcp_new_stream" needs 2 additional parameters
Bachar
Don't know if this just happened to me, but in any case the fix is to add the python-dev to the needed packages for compilation.
Also - libpthread-dev should be installed with this name libpthread-stubs0-dev
I would update the instructions :)
Thank you!
I am going through the examples to figure out how libntoh
works and to make a more powerful example. as well In the process, I ran across this very confusing code inside of the tcp_callback
. The code causes an error in the clang-3.7
compiler:
megahall.c:283:17: warning: code will never be executed [-Wunreachable-code]
switch (extra) {
The code being hit is below. @sch3m4 can you explain what this code is actually supposed to be doing so I can correct this funny switch
and get it to work properly in a standards compliant way instead?
switch ( reason )
{
switch ( extra )
{
case NTOH_REASON_MAX_SYN_RETRIES_REACHED:
case NTOH_REASON_MAX_SYNACK_RETRIES_REACHED:
case NTOH_REASON_HSFAILED:
case NTOH_REASON_EXIT:
case NTOH_REASON_TIMEDOUT:
case NTOH_REASON_CLOSED:
inet_ntop ( AF_INET6 , (void*) &stream->client.addr , src , INET6_ADDRSTRLEN );
if ( extra == NTOH_REASON_CLOSED )
fprintf ( stderr , "\n\t+ Connection closed by %s (%s)" , stream->closedby == NTOH_CLOSEDBY_CLIENT ? "Client" : "Server" , src );
else
fprintf ( stderr , "\n\t+ %s/%s - %s" , ntoh_get_reason ( reason ) , ntoh_get_reason ( extra ) , ntoh_tcp_get_status ( stream->status ) );
break;
}
break;
/* Data segment */
case NTOH_REASON_DATA:
fprintf ( stderr , " | Data segment | Bytes: %i" , seg->payload_len );
/* write data */
write_data( (ppeer_info_t) seg->user_data );
if ( extra != 0 )
fprintf ( stderr , " - %s" , ntoh_get_reason ( extra ) );
break;
}
In tcpreassembly.c handle_closing_connection func
, why at the end call the send_peer_segments
again while at the beginning or this func already call it?
(origin->segments) shows up as a null pointer.
Possible fix (?):
static unsigned short count = 0;
pntoh_tcp_peer_t peer = origin;
pntoh_tcp_peer_t side = destination;
if ( segment != 0 )
queue_segment ( session , origin , segment );
send_peer_segments ( session , stream , destination , origin , origin->next_seq , 0 , 0 );
/*if ( ! origin->segments )
return;*/
if ( count++ < 1 )
{
handle_closing_connection ( session , stream , destination , origin , 0 );
count = 0;
}
if ( ! origin->segments )
return;
In build_datagram (at ipv4defrag.c:225), there's no return value check upon a calloc.
First of all, I'd like to thank you for amazing easy-to-use library. It's really useful when one has to deal with TCP/IP packages.
However, I've found no way to let IPv6 communicate with TCP. For example, in ipv6_callback one may have (protocol == IPPROTO_TCP)
, but it is impossible to use tcp_send since ntoh_tcp_add_segment
has its argument as struct ip*
.
I guess that I'm missing something, since ipv6defrag.h
contains a lot of functions to work with IPv6 packets. I couldn't find any way to bind these functions to TCP. Is it possible? Thanks!
In the file tcpreassembly.c line 1264, there is a lock done just before NTOH_TCP_PORTS_MISMATCH check.
In case of return (line 1271=, there is no unlock_access done.
--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/35753453-no-unlock_access-in-case-of-ntoh_tcp_ports_mismatch?utm_campaign=plugin&utm_content=tracker%2F773156&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F773156&utm_medium=issues&utm_source=github).Fix:
int ntoh_tcp_add_segment (...)
{
.....
/* get origin and destination */
- if ( stream->tuple.source == ip->ip_src.s_addr )
+ if ( stream->tuple.source == ip->ip_src.s_addr && stream->tuple.sport == tcp->th_sport )
{
origin = &stream->client;
destination = &stream->server;
.....
}
When we search for a fragment from a particular ipv4 stream, we use a key that was generated by the code to match it:
inline static ntoh_ipv4_key_t ip_get_hashkey ( pntoh_ipv4_session_t session , pntoh_ipv4_tuple4_t tuple4 )
{
ntoh_ipv4_key_t ret = 0;
if ( !tuple4 || !session )
return ret;
ret = tuple4->source ^ tuple4->destination;
ret ^= ( ret >> 16 ) ^ tuple4->id;
ret ^= ( ret >> 8 ) ^ tuple4->protocol;
ret &= session->flows->table_size - 1;
return ret;
}
ret here is not suitable to identify which stream to match the ipv4 fragments to, as different values for id, protocol and destination may get matched up to the same stream. (Try a fragment with the same protocol and id, but switch around the source and destination ip addresses, for example).
We need to implement a proper equals_to function in common.c to match the streams up if they have the same hash value. I have an attempt that I will submit soon.
I am running into some difficulty managing the objects places into seg->user_data
.
NTOH_SYNCHRONIZING
or any error returns from ntoh_tcp_add_segment
, the example does this for failed packets, it causes a double free in valgrind
.free
always after ntoh_tcp_add_segment
returns, it causes access errors inside the TCP callback.seg->user_data
.What is the proper way to manage the seg->user_data
memory? This is very confusing.
I have been observing dangling state (== CLOSING) when the stack receives concurrent FIN/ACKs from both the client and the server.
See the trace below (I added a few printf's in handle_closing_connection):
->FIN/ACK
add segment: stream: ESTABLISHED, origin: ESTABLISHED, destination: ESTABLISHED
ports: 50319, 3025
origin: 140582205203104, destination: 140582205203192, peer: 140582205203104, side: 140582205203192
origin->segments->seq: 156365, origin->next_seq: 156365, origin->segments->ack: 260, destination->next_seq: 260
status: stream: ESTABLISHED, origin: ESTABLISHED, destination: ESTABLISHED, peer: ESTABLISHED, side: ESTABLISHED
new status: stream: CLOSING, origin: FIN_WAIT1, destination: CLOSE_WAIT, peer: FIN_WAIT1, side: CLOSE_WAIT
<-FIN/ACK
add segment: stream: CLOSING, origin: CLOSE_WAIT, destination: FIN_WAIT1
ports: 3025, 50319
origin: 140582205203192, destination: 140582205203104, peer: 140582205203104, side: 140582205203192
origin->segments->seq: 260, origin->next_seq: 260, origin->segments->ack: 156365, destination->next_seq: 156366
seq cond failed
->ACK
add segment: stream: CLOSING, origin: FIN_WAIT1, destination: CLOSE_WAIT
ports: 50319, 3025
origin: 140582205203192, destination: 140582205203104, peer: 140582205203104, side: 140582205203192
origin->segments->seq: 260, origin->next_seq: 260, origin->segments->ack: 156365, destination->next_seq: 156366
seq cond failed
origin: 140582205203104, destination: 140582205203192, peer: 140582205203104, side: 140582205203192
origin->segments->seq: 156366, origin->next_seq: 156366, origin->segments->ack: 261, destination->next_seq: 260
seq cond failed
<-ACK
add segment: stream: CLOSING, origin: CLOSE_WAIT, destination: FIN_WAIT1
ports: 3025, 50319
origin: 140582205203104, destination: 140582205203192, peer: 140582205203104, side: 140582205203192
origin->segments->seq: 156366, origin->next_seq: 156366, origin->segments->ack: 261, destination->next_seq: 260
seq cond failed
origin: 140582205203192, destination: 140582205203104, peer: 140582205203104, side: 140582205203192
origin->segments->seq: 260, origin->next_seq: 260, origin->segments->ack: 156365, destination->next_seq: 156366
seq cond failed
Is the code putting the fragments in ascending/descending order..but while trying to understand the code, I felt like there is no particular order..also can anyone explain why the comment 'Based on 4.3 BSD, we will give priority to fragments with lower offset to avoid teardrop attack'
I am not sure is this the right forum to ask doubts..if not where to post queries regarding libntoh
During libntoh testing, it was shown that libntoh never actually finds a stream, but always creates a new one. Here is an example source file.
https://gist.github.com/ghostmansd/5cb5b6f41fe72e554696
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.