"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "base/tcppack.c" between
ssldump-0.9b3.tar.gz and ssldump-1.3.tar.gz

About: ssldump is an SSLv3/TLS network protocol analyzer.

tcppack.c  (ssldump-0.9b3):tcppack.c  (ssldump-1.3)
skipping to change at line 44 skipping to change at line 44
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMA GE. OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMA GE.
$Id: tcppack.c,v 1.11 2002/09/09 21:02:58 ekr Exp $ $Id: tcppack.c,v 1.11 2002/09/09 21:02:58 ekr Exp $
ekr@rtfm.com Tue Dec 29 12:43:39 1998 ekr@rtfm.com Tue Dec 29 12:43:39 1998
*/ */
static char *RCSSTRING="$Id: tcppack.c,v 1.11 2002/09/09 21:02:58 ekr Exp $";
#include "network.h" #include "network.h"
#ifndef _WIN32 #ifndef _WIN32
# include <sys/socket.h> # include <sys/socket.h>
# include <arpa/inet.h> # include <arpa/inet.h>
# ifndef LINUX # ifndef LINUX
# include <netinet/tcp_seq.h> # include <netinet/tcp_seq.h>
# else # else
# define SEQ_LT(x,y) ((int)((x)-(y))<0) # define SEQ_LT(x,y) ((int)((x)-(y))<0)
# endif # endif
#else #else
skipping to change at line 81 skipping to change at line 79
int process_tcp_packet(handler,ctx,p) int process_tcp_packet(handler,ctx,p)
proto_mod *handler; proto_mod *handler;
proto_ctx *ctx; proto_ctx *ctx;
packet *p; packet *p;
{ {
int r,_status; int r,_status;
int direction; int direction;
stream_data *stream; stream_data *stream;
tcp_conn *conn; tcp_conn *conn;
if(p->len < 20)
ABORT(1);
p->tcp=(struct tcphdr *)p->data; p->tcp=(struct tcphdr *)p->data;
print_tcp_packet(p); print_tcp_packet(p);
if(r=tcp_find_conn(&conn,&direction,&p->ip->ip_src, if((r=tcp_find_conn(&conn,&direction,&p->ip->ip_src,
ntohs(p->tcp->th_sport),&p->ip->ip_dst,ntohs(p->tcp->th_dport))){ ntohs(p->tcp->th_sport),&p->ip->ip_dst,ntohs(p->tcp->th_dport)))){
if(r!=R_NOT_FOUND) if(r!=R_NOT_FOUND)
ABORT(r); ABORT(r);
/*Note that we MUST receive the 3-way handshake in the if((p->tcp->th_flags & TH_SYN)!=TH_SYN){
proper order. This shouldn't be a problem, though, DBG((0,"TCP: rejecting packet from unknown connection, seq: %u\n",ntohl(p
except for simultaneous connects*/ ->tcp->th_seq)));
if((p->tcp->th_flags & (TH_SYN|TH_ACK))!=TH_SYN){
DBG((0,"TCP: rejecting packet from unknown connection\n"));
return(0); return(0);
} }
DBG((0,"SYN1\n")); if((r=new_connection(handler,ctx,p,&conn)))
if(r=new_connection(handler,ctx,p,&conn))
ABORT(r); ABORT(r);
conn->i2r.seq=ntohl(p->tcp->th_seq)+1;
return(0); return(0);
} }
stream=direction==DIR_R2I?&conn->r2i:&conn->i2r; stream=direction==DIR_R2I?&conn->r2i:&conn->i2r;
memcpy(&conn->last_seen_time,&p->ts,sizeof(struct timeval));
switch(conn->state){ switch(conn->state){
case TCP_STATE_SYN1: case TCP_STATE_SYN1:
if(direction != DIR_R2I) if(direction == DIR_R2I && (p->tcp->th_flags & TH_SYN)) {
break; DBG((0,"SYN2 seq: %u",ntohl(p->tcp->th_seq)));
if((p->tcp->th_flags & (TH_SYN|TH_ACK))!=(TH_SYN|TH_ACK)) conn->r2i.seq=ntohl(p->tcp->th_seq)+1;
break; conn->r2i.ack=ntohl(p->tcp->th_ack)+1;
conn->r2i.seq=ntohl(p->tcp->th_seq)+1; conn->state=TCP_STATE_ACK;
conn->r2i.ack=ntohl(p->tcp->th_ack)+1; }
conn->state=TCP_STATE_SYN2; break;
DBG((0,"SYN2\n"));
break;
case TCP_STATE_SYN2: case TCP_STATE_SYN2:
if(direction == DIR_I2R && (p->tcp->th_flags & TH_SYN)) {
DBG((0,"SYN1 seq: %u",ntohl(p->tcp->th_seq)));
conn->i2r.seq=ntohl(p->tcp->th_seq)+1;
conn->i2r.ack=ntohl(p->tcp->th_ack)+1;
conn->state=TCP_STATE_ACK;
}
break;
case TCP_STATE_ACK:
{ {
char *sn=0,*dn=0; char *sn=0,*dn=0;
if(direction != DIR_I2R) if(direction != DIR_I2R)
break; break;
DBG((0,"ACK\n")); DBG((0,"ACK seq: %u",ntohl(p->tcp->th_seq)));
conn->i2r.ack=ntohl(p->tcp->th_ack)+1; conn->i2r.ack=ntohl(p->tcp->th_ack)+1;
lookuphostname(&conn->i_addr,&sn); lookuphostname(&conn->i_addr,&sn);
lookuphostname(&conn->r_addr,&dn); lookuphostname(&conn->r_addr,&dn);
if(NET_print_flags & NET_PRINT_TYPESET) if(!(NET_print_flags & NET_PRINT_JSON)) {
printf("\\fC"); if(NET_print_flags & NET_PRINT_TYPESET)
printf("New TCP connection #%d: %s(%d) <-> %s(%d)\n", printf("\\fC");
conn->conn_number, printf("New TCP connection #%d: %s(%d) <-> %s(%d)\n",
sn,conn->i_port, conn->conn_number,
dn,conn->r_port); sn,conn->i_port,
if(NET_print_flags & NET_PRINT_TYPESET) dn,conn->r_port);
printf("\\fR"); if(NET_print_flags & NET_PRINT_TYPESET)
printf("\\fR");
}
conn->state=TCP_STATE_ESTABLISHED; conn->state=TCP_STATE_ESTABLISHED;
free(sn); free(sn);
free(dn); free(dn);
} }
case TCP_STATE_ESTABLISHED: case TCP_STATE_ESTABLISHED:
case TCP_STATE_FIN1: case TCP_STATE_FIN1:
{ {
UINT4 length;
if(p->tcp->th_flags & TH_SYN) if(p->tcp->th_flags & TH_SYN)
break; break;
length=p->len - (p->tcp->th_off * 4); if((r=process_data_segment(conn,handler,p,stream,direction)))
if(r=process_data_segment(conn,handler,p,stream,direction))
ABORT(r); ABORT(r);
} }
break; break;
default: default:
break; break;
} }
if(conn->state==TCP_STATE_CLOSED) if(conn->state==TCP_STATE_CLOSED)
tcp_destroy_conn(conn); tcp_destroy_conn(conn);
skipping to change at line 174 skipping to change at line 176
static int new_connection(handler,ctx,p,connp) static int new_connection(handler,ctx,p,connp)
proto_mod *handler; proto_mod *handler;
proto_ctx *ctx; proto_ctx *ctx;
packet *p; packet *p;
tcp_conn **connp; tcp_conn **connp;
{ {
int r,_status; int r,_status;
tcp_conn *conn=0; tcp_conn *conn=0;
if(r=tcp_create_conn(&conn,&p->ip->ip_src,ntohs(p->tcp->th_sport), if ((p->tcp->th_flags & (TH_SYN|TH_ACK))==TH_SYN) {
&p->ip->ip_dst,ntohs(p->tcp->th_dport))) if((r=tcp_create_conn(&conn,&p->ip->ip_src,ntohs(p->tcp->th_sport),
ABORT(r); &p->ip->ip_dst,ntohs(p->tcp->th_dport))))
ABORT(r);
conn->state=TCP_STATE_SYN1; DBG((0,"SYN1 seq: %u",ntohl(p->tcp->th_seq)));
conn->i2r.seq=ntohl(p->tcp->th_seq)+1;
conn->i2r.ack=ntohl(p->tcp->th_ack)+1;
conn->state=TCP_STATE_SYN1;
} else { // SYN&ACK comes first somehow
if((r=tcp_create_conn(&conn,&p->ip->ip_dst,ntohs(p->tcp->th_dport),
&p->ip->ip_src,ntohs(p->tcp->th_sport))))
ABORT(r);
DBG((0,"SYN2 seq: %u",ntohl(p->tcp->th_seq)));
conn->r2i.seq=ntohl(p->tcp->th_seq)+1;
conn->r2i.ack=ntohl(p->tcp->th_ack)+1;
conn->state=TCP_STATE_SYN2;
}
memcpy(&conn->start_time,&p->ts,sizeof(struct timeval)); memcpy(&conn->start_time,&p->ts,sizeof(struct timeval));
if(r=create_proto_handler(handler,ctx,&conn->analyzer,conn,&p->ts)) memcpy(&conn->last_seen_time,&p->ts,sizeof(struct timeval));
if((r=create_proto_handler(handler,ctx,&conn->analyzer,conn,&p->ts)))
ABORT(r); ABORT(r);
*connp=conn; *connp=conn;
_status=0; _status=0;
abort: abort:
return(_status); return(_status);
} }
/*#define STRIM(_seq,s) { \ /*#define STRIM(_seq,s) { \
int l;\ int l;\
skipping to change at line 225 skipping to change at line 240
int direction; int direction;
{ {
int r,_status; int r,_status;
tcp_seq seq,right_edge; tcp_seq seq,right_edge;
segment _seg; segment _seg;
segment *seg,*nseg=0; segment *seg,*nseg=0;
long l; long l;
l=p->len - p->tcp->th_off * 4; l=p->len - p->tcp->th_off * 4;
if(l < 0) {
fprintf(stderr,"Malformed packet, computed TCP segment size is negative,
skipping ...\n");
return(0);
}
if(stream->close){ if(stream->close){
DBG((0,"Rejecting packet received after FIN")); DBG((0,"Rejecting packet received after FIN: %u:%u(%u)",
ntohl(p->tcp->th_seq),ntohl(p->tcp->th_seq+l),l));
return(0); return(0);
} }
/*The idea here is to pass all available segments /*The idea here is to pass all available segments
to the analyzer at once. Since we want to preserve to the analyzer at once. Since we want to preserve
the segment packet data, we pass the data as a linked list of the segment packet data, we pass the data as a linked list of
segments*/ segments*/
seq=ntohl(p->tcp->th_seq); seq=ntohl(p->tcp->th_seq);
/*Add ACK processing logic here <TODO>*/ /*Add ACK processing logic here <TODO>*/
if(p->tcp->th_flags & TH_ACK){ if(p->tcp->th_flags & TH_ACK){
long acknum,acked; long acknum,acked;
acknum=ntohl(p->tcp->th_ack); acknum=ntohl(p->tcp->th_ack);
acked=acknum-stream->ack; acked=acknum-stream->ack;
if(acked && !l){ if(acked && !l){
/* /*
if(r=timestamp_diff(&p->ts,&conn->start_time,&dt)) if((r=timestamp_diff(&p->ts,&conn->start_time,&dt)))
ERETURN(r); ERETURN(r);
printf("%d%c%4.4d ",dt.tv_sec,'.',dt.tv_usec/100); printf("%d%c%4.4d ",dt.tv_sec,'.',dt.tv_usec/100);
if(direction == DIR_R2I) if(direction == DIR_R2I)
printf("S>C "); printf("S>C ");
else else
printf("C>S "); printf("C>S ");
printf("ACK (%d)\n",acked); */ printf("ACK (%d)\n",acked); */
} }
skipping to change at line 275 skipping to change at line 296
if(SEQ_LT(stream->seq,seq)){ if(SEQ_LT(stream->seq,seq)){
/* Out of order segment */ /* Out of order segment */
tcp_seq left_edge; tcp_seq left_edge;
for(seg=0;seg;seg=seg?seg->next:stream->oo_queue){ for(seg=0;seg;seg=seg?seg->next:stream->oo_queue){
if(seg->next->s_seq > seq) if(seg->next->s_seq > seq)
break; break;
} }
if(!(nseg=(segment *)calloc(sizeof(segment),1))) if(!(nseg=(segment *)calloc(1,sizeof(segment))))
ABORT(R_NO_MEMORY); ABORT(R_NO_MEMORY);
if(r=packet_copy(p,&nseg->p)) if((r=packet_copy(p,&nseg->p)))
ABORT(r); ABORT(r);
nseg->s_seq=seq; nseg->s_seq=seq;
/*Insert this segment into the reassembly queue*/ /*Insert this segment into the reassembly queue*/
if(seg){ if(seg){
nseg->next=seg->next; nseg->next=seg->next;
seg->next=nseg; seg->next=nseg;
} }
else{ else{
nseg->next=stream->oo_queue; nseg->next=stream->oo_queue;
skipping to change at line 337 skipping to change at line 358
} }
/*Note that this logic is broken because it doesn't /*Note that this logic is broken because it doesn't
do the CLOSE_WAIT/FIN_WAIT stuff, but it's probably do the CLOSE_WAIT/FIN_WAIT stuff, but it's probably
close enough, since this is a higher level protocol analyzer, close enough, since this is a higher level protocol analyzer,
not a TCP analyzer*/ not a TCP analyzer*/
if(seg->p->tcp->th_flags & (TH_FIN) ){ if(seg->p->tcp->th_flags & (TH_FIN) ){
if(conn->state == TCP_STATE_ESTABLISHED) if(conn->state == TCP_STATE_ESTABLISHED)
conn->state=TCP_STATE_FIN1; conn->state=TCP_STATE_FIN1;
else else
conn->state=TCP_STATE_CLOSED; conn->state=TCP_STATE_CLOSED;
} }
free_tcp_segment_queue(stream->oo_queue);
stream->oo_queue=seg->next; stream->oo_queue=seg->next;
seg->next=0; seg->next=0;
stream->seq=seg->s_seq + seg->len; stream->seq=seg->s_seq + seg->len;
if(r=conn->analyzer->vtbl->data(conn->analyzer->obj,&_seg,direction)) DBG((0,"Analyzing segment: %u:%u(%u)", seg->s_seq, seg->s_seq+seg->len,
seg->len));
if((r=conn->analyzer->vtbl->data(conn->analyzer->obj,&_seg,direction)))
{
DBG((0,"ABORT due to segment: %u:%u(%u)", seg->s_seq, seg->s_seq+seg->
len, seg->len));
ABORT(r); ABORT(r);
}
} }
if(stream->close){ if(stream->close){
if(r=conn->analyzer->vtbl->close(conn->analyzer->obj,p,direction)) DBG((0,"Closing with segment: %u:%u(%u)", seg->s_seq, stream->seq, seg->
ABORT(r); len));
if((r=conn->analyzer->vtbl->close(conn->analyzer->obj,p,direction))) {
DBG((0,"ABORT due to segment: %u:%u(%u)", seg->s_seq, stream->seq, seg
->len));
ABORT(r);
}
} }
free_tcp_segment_queue(_seg.next); free_tcp_segment_queue(_seg.next);
} }
_status=0; _status=0;
abort: abort:
return(_status); return(_status);
} }
skipping to change at line 372 skipping to change at line 400
packet *p; packet *p;
{ {
char *src=0,*dst=0; char *src=0,*dst=0;
if(!(NET_print_flags & NET_PRINT_TCP_HDR)) if(!(NET_print_flags & NET_PRINT_TCP_HDR))
return(0); return(0);
lookuphostname(&p->ip->ip_src,&src); lookuphostname(&p->ip->ip_src,&src);
lookuphostname(&p->ip->ip_dst,&dst); lookuphostname(&p->ip->ip_dst,&dst);
printf("TCP: %s(%d) -> %s(%d) ", if(!(NET_print_flags & NET_PRINT_JSON)) {
src, printf("TCP: %s(%d) -> %s(%d) ",
ntohs(p->tcp->th_sport), src,
dst, ntohs(p->tcp->th_sport),
ntohs(p->tcp->th_dport)); dst,
ntohs(p->tcp->th_dport));
printf("Seq %u.(%d) ",
ntohl(p->tcp->th_seq), printf("Seq %u.(%d) ",
p->len - p->tcp->th_off *4); ntohl(p->tcp->th_seq),
p->len - p->tcp->th_off *4);
if(p->tcp->th_flags & TH_ACK)
printf("ACK %u ",ntohl(p->tcp->th_ack)); if(p->tcp->th_flags & TH_ACK)
printf("ACK %u ",ntohl(p->tcp->th_ack));
if(p->tcp->th_flags & TH_FIN)
printf("FIN "); if(p->tcp->th_flags & TH_FIN)
if(p->tcp->th_flags & TH_SYN) printf("FIN ");
printf("SYN "); if(p->tcp->th_flags & TH_SYN)
if(p->tcp->th_flags & TH_RST) printf("SYN ");
printf("RST "); if(p->tcp->th_flags & TH_RST)
if(p->tcp->th_flags & TH_PUSH) printf("RST ");
printf("PUSH "); if(p->tcp->th_flags & TH_PUSH)
if(p->tcp->th_flags & TH_URG) printf("PUSH ");
printf("URG "); if(p->tcp->th_flags & TH_URG)
printf("URG ");
printf("\n");
printf("\n");
}
free(src); free(src);
free(dst); free(dst);
return(0); return(0);
} }
int STRIM(_seq,s) int STRIM(_seq,s)
UINT4 _seq; UINT4 _seq;
segment *s; segment *s;
{ {
int l; int l;
 End of changes. 27 change blocks. 
74 lines changed or deleted 110 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)