/** * @brief Send a TCP segment to libntoh */ void send_tcp_segment ( struct ip *iphdr , pntoh_tcp_callback_t callback ) { ppeer_info_t pinfo; ntoh_tcp_tuple5_t tcpt5; pntoh_tcp_stream_t stream; struct tcphdr *tcp; size_t size_ip; size_t total_len; size_t size_tcp; size_t size_payload; unsigned char *payload; int ret; unsigned int error; size_ip = iphdr->ip_hl * 4; total_len = ntohs( iphdr->ip_len ); tcp = (struct tcphdr*)((unsigned char*)iphdr + size_ip); if ( (size_tcp = tcp->th_off * 4) < sizeof(struct tcphdr) ) return; payload = (unsigned char *)iphdr + size_ip + size_tcp; size_payload = total_len - ( size_ip + size_tcp ); ntoh_tcp_get_tuple5 ( (void*)iphdr , tcp , &tcpt5 ); /* find the stream or creates a new one */ if ( !( stream = ntoh_tcp_find_stream( tcp_session , &tcpt5 ) ) ) if ( ! ( stream = ntoh_tcp_new_stream( tcp_session , &tcpt5, callback , 0 , &error , 1 , 1 ) ) ) { fprintf ( stderr , "\n[e] Error %d creating new stream: %s" , error , ntoh_get_errdesc ( error ) ); return; } if ( size_payload > 0 ) pinfo = get_peer_info ( payload , size_payload , &tcpt5 ); else pinfo = 0; /* add this segment to the stream */ switch ( ( ret = ntoh_tcp_add_segment( tcp_session , stream, (void*)iphdr, total_len, (void*)pinfo ) ) ) { case NTOH_OK: break; case NTOH_SYNCHRONIZING: free_peer_info ( pinfo ); break; default: fprintf( stderr, "\n[e] Error %d adding segment: %s", ret, ntoh_get_retval_desc( ret ) ); free_peer_info ( pinfo ); break; } return; }
/* TCP Callback */ void tcp_callback ( pntoh_tcp_stream_t stream , pntoh_tcp_peer_t orig , pntoh_tcp_peer_t dest , pntoh_tcp_segment_t seg , int reason , int extra ) { /* receive data only from the peer given by the user */ if ( receive == RECV_CLIENT && stream->server.receive ) { stream->server.receive = 0; return; }else if ( receive == RECV_SERVER && stream->client.receive ) { stream->client.receive = 0; return; } fprintf ( stderr , "\n[%s] %s:%d (%s | Window: %lu) ---> " , ntoh_tcp_get_status ( stream->status ) , inet_ntoa( *(struct in_addr*) &orig->addr ) , ntohs(orig->port) , ntoh_tcp_get_status ( orig->status ) , orig->totalwin ); fprintf ( stderr , "%s:%d (%s | Window: %lu)\n\t" , inet_ntoa( *(struct in_addr*) &dest->addr ) , ntohs(dest->port) , ntoh_tcp_get_status ( dest->status ) , dest->totalwin ); if ( seg != 0 ) fprintf ( stderr , "SEQ: %lu ACK: %lu Next SEQ: %lu" , seg->seq , seg->ack , orig->next_seq ); switch ( reason ) { /* 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; default: 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: if ( extra == NTOH_REASON_CLOSED ) fprintf ( stderr , "\n\t+ Connection closed by %s (%s)" , stream->closedby == NTOH_CLOSEDBY_CLIENT ? "Client" : "Server" , inet_ntoa( *(struct in_addr*) &(stream->client.addr) ) ); else fprintf ( stderr , "\n\t+ %s/%s - %s" , ntoh_get_reason ( reason ) , ntoh_get_reason ( extra ) , ntoh_tcp_get_status ( stream->status ) ); break; default: break; } break; } if ( seg != 0 ) free_peer_info ( (ppeer_info_t) seg->user_data ); fprintf ( stderr , "\n" ); return; }
/** * @brief Send a TCP segment to libntoh */ void send_tcp_segment ( struct ip *iphdr , pntoh_tcp_callback_t callback ) { ppeer_info_t pinfo; ntoh_tcp_tuple5_t tcpt5; pntoh_tcp_stream_t stream; struct tcphdr *tcp; size_t size_ip; size_t total_len; size_t size_tcp; size_t size_payload; unsigned char *payload; int32_t ret; unsigned int error; size_ip = iphdr->ip_hl * 4; total_len = ntohs( iphdr->ip_len ); tcp = (struct tcphdr*)((unsigned char*)iphdr + size_ip); if ( (size_tcp = tcp->th_off * 4) < sizeof(struct tcphdr) ) { return; } payload = (unsigned char *)iphdr + size_ip + size_tcp; size_payload = total_len - ( size_ip + size_tcp ); ntoh_tcp_get_tuple5 ( iphdr , tcp , &tcpt5 ); /* find the stream or creates a new one */ if ( !( stream = ntoh_tcp_find_stream( tcp_session , &tcpt5 ) ) ) { if ( ! ( stream = ntoh_tcp_new_stream( tcp_session , &tcpt5, callback , 0 , &error , 1 , 1 ) ) ) { if (DEBUG) { fprintf ( stderr , "\n[e] Error %d creating new stream: %s" , error , ntoh_get_errdesc ( error ) ); } return; } } if ( size_payload > 0 ) { pinfo = get_peer_info ( payload , size_payload , &tcpt5 ); } else { pinfo = 0; } if (pinfo != 0) { /* HERE - determine if this is a packet type we're interested in */ //if (Contains((char *)payload, "HTTP") && (Contains((char *)payload, "GET") || Contains((char *)payload, "POST") || Contains((char *)payload, "HEAD"))) if (ntohs(tcpt5.dport) == 80) { pending_more_hdr_data = extractHttpHdr((const char *)(payload)); if (pending_more_hdr_data == 0) { size_t l = (strlen((const char *)(pinfo->path))); i = 0; while (i < l) { snc.mem.t5s[(snc.smem.shm[CTL][POS]) - 1][i] = (sig_atomic_t)(pinfo->path[i]); i++; } snc.mem.t5s[(snc.smem.shm[CTL][POS]) - 1][i] = (sig_atomic_t)((const char)'\0'); if (DEBUG) { write(2, "\n\t[i] --- tcp tuple 5 --- ", 27); write(2, (const char *)(pinfo->path), strlen((const char *)(pinfo->path))); fflush(stderr); } extractSig(); ret = dumpToShm(); if(ret != 0) { if (DEBUG) { fprintf(stderr, "\n\t[Error] --- Unable to dump HTTP header to shared memory\n\t\tReason: %s\n", ret == CRING ? "CRING" : (ret == PWING ? "PWING" : "Unknown")); } } else { if (DEBUG) { write(2, "\n\tSuccessfully dumped signature to shared memory\n", 49); } } ret = 0; } } } /* add this segment to the stream */ switch ( ( ret = ntoh_tcp_add_segment( tcp_session , stream, iphdr, total_len, (void*)pinfo ) ) ) { case NTOH_OK: break; case NTOH_SYNCHRONIZING: free_peer_info ( pinfo ); break; default: if (DEBUG) { fprintf( stderr, "\n[e] Error %d adding segment: %s", ret, ntoh_get_retval_desc( ret ) ); } free_peer_info ( pinfo ); break; } return; }