00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <libnet.h>
00022 #include <pcap.h>
00023 #include <unistd.h>
00024 #include <sys/time.h>
00025 #include <stdio.h>
00026 #include <sys/types.h>
00027 #include <arpa/inet.h>
00028 #include <stdlib.h>
00029 #include <ctype.h>
00030 #include <netdb.h>
00031 #include <netinet/in.h>
00032
00033 #include "traceproto.h"
00034 #include "tp_miscfunc.h"
00035 #include "tp_packet.h"
00036
00037 #ifdef HAVE_LIBDMALLOC
00038 #include <dmalloc.h>
00039 #endif
00040
00041
00042
00043
00044
00045 void build_packet( void )
00046 {
00047 switch ( packet.protocol_number )
00048 {
00049 case IPPROTO_TCP:
00050 state.tcp_h = libnet_build_tcp(
00051 packet.src_port,
00052 packet.dst_port,
00053 libnet_get_prand(LIBNET_PRu32),
00054 libnet_get_prand(LIBNET_PRu32),
00055 packet.tcp_flags,
00056 1500,
00057 0,
00058 0,
00059 LIBNET_TCP_H + behavior.payload_size,
00060 packet.payload,
00061 behavior.payload_size,
00062 state.packet,
00063 state.tcp_h );
00064 break;
00065 case IPPROTO_UDP:
00066 state.udp_h = libnet_build_udp(
00067 packet.src_port,
00068 packet.dst_port,
00069 LIBNET_UDP_H + behavior.payload_size,
00070 0,
00071 packet.payload,
00072 behavior.payload_size,
00073 state.packet,
00074 state.udp_h );
00075 break;
00076 case IPPROTO_ICMP:
00077 state.icmp_h = libnet_build_icmpv4_echo (
00078 ICMP_ECHO,
00079 0,
00080 0,
00081 libnet_get_prand ( LIBNET_PRu16 ),
00082 libnet_get_prand ( LIBNET_PRu16 ),
00083 packet.payload,
00084 behavior.payload_size,
00085 state.packet,
00086 state.icmp_h );
00087 break;
00088 default:
00089 printf ( "protocol error\n" );
00090 tixe ( tixe_cleanup, 1 );
00091 break;
00092 }
00093 }
00094
00095
00096
00097
00098
00099 int parse_tcp_packet( const u_char * raw_packet )
00100 {
00101 struct libnet_tcp_hdr * tcp_hdr;
00102
00103 if ( state.ip_hdr->ip_ttl >= 1 )
00104 state.low_ttl = YES;
00105
00106
00107 tcp_hdr = ( struct libnet_tcp_hdr * ) tp_align ( raw_packet,
00108 0,
00109 sizeof ( struct libnet_tcp_hdr ) );
00110
00111 account_packet ( state.trip_time );
00112
00113 switch ( tcp_hdr->th_flags )
00114 {
00115 case ( TH_ACK | TH_RST ):
00116 behavior.report( TP_OUT_HOP_INFO, & state.ip_hdr->ip_src, TP_TYPE_ACKRST );
00117 state.packet_match = TP_PACKET_DONE;
00118 state.target_response = YES;
00119 break;
00120 case ( TH_ACK | TH_SYN ):
00121 behavior.report( TP_OUT_HOP_INFO, & state.ip_hdr->ip_src, TP_TYPE_SYNACK );
00122 state.packet_match = TP_PACKET_DONE;
00123 state.target_response = YES;
00124 break;
00125 case TH_SYN:
00126 behavior.report( TP_OUT_HOP_INFO, & state.ip_hdr->ip_src, TP_TYPE_SYN );
00127 state.packet_match = TP_PACKET_DONE;
00128 state.target_response = YES;
00129 break;
00130 case ( TH_SYN | TH_ACK | TH_ECE | TH_CWR ):
00131 behavior.report( TP_OUT_HOP_INFO, & state.ip_hdr->ip_src, TP_TYPE_SEC );
00132 state.packet_match = TP_PACKET_DONE;
00133 state.target_response = YES;
00134 break;
00135 case TH_RST:
00136 behavior.report( TP_OUT_HOP_INFO, & state.ip_hdr->ip_src, TP_TYPE_RST );
00137 state.packet_match = TP_PACKET_DONE;
00138 state.target_response = YES;
00139 break;
00140 case TH_FIN:
00141 behavior.report( TP_OUT_HOP_INFO, & state.ip_hdr->ip_src, TP_TYPE_FIN );
00142 state.packet_match = TP_PACKET_DONE;
00143 state.target_response = YES;
00144 break;
00145 case TH_ACK:
00146 behavior.report( TP_OUT_HOP_INFO, & state.ip_hdr->ip_src, TP_TYPE_ACK );
00147 state.packet_match = TP_PACKET_DONE;
00148 state.target_response = YES;
00149 break;
00150 default:
00151 behavior.report( TP_OUT_HOP_INFO, & state.ip_hdr->ip_src, TP_TYPE_OTHER );
00152 break;
00153 }
00154
00155
00156 return ( state.packet_match == TP_PACKET_NO ) ? 0 : 1;
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166 int parse_udp_packet( const u_char * raw_packet )
00167 {
00168 struct libnet_udp_hdr * udp_hdr;
00169
00170 if ( state.ip_hdr->ip_ttl >= 1 )
00171 state.low_ttl = YES;
00172
00173
00174 udp_hdr = ( struct libnet_udp_hdr * ) tp_align ( raw_packet,
00175 0,
00176 sizeof ( struct libnet_udp_hdr ) );
00177
00178 account_packet ( state.trip_time );
00179
00180 behavior.report( TP_OUT_HOP_INFO, & state.ip_hdr->ip_src, TP_TYPE_UDP );
00181 state.packet_match = TP_PACKET_DONE;
00182 state.target_response = YES;
00183
00184 return ( state.packet_match == TP_PACKET_NO ) ? 0 : 1;
00185 }
00186
00187
00188
00189
00190
00191
00192
00193 int parse_icmp_packet( const u_char * raw_packet )
00194 {
00195 const struct libnet_icmpv4_hdr * icmp_hdr;
00196 const struct libnet_ipv4_hdr * icmp_payload;
00197
00198 int icmp_payload_offset = 8;
00199
00200 icmp_hdr = ( const struct libnet_icmpv4_hdr * ) & raw_packet [ 0 ];
00201 icmp_payload = ( const struct libnet_ipv4_hdr * ) & raw_packet [ icmp_payload_offset ];
00202
00203 if ( icmp_payload->ip_id != tp_ntol ( packet.ip_id ) )
00204 return ( state.packet_match == TP_PACKET_NO );
00205
00206 account_packet ( state.trip_time );
00207
00208 if ( icmp_hdr->icmp_type == ICMP_ECHOREPLY )
00209 {
00210 behavior.report( TP_OUT_HOP_INFO, & state.ip_hdr->ip_src, TP_TYPE_ECHOREPLY );
00211 state.packet_match = TP_PACKET_MATCH;
00212 state.target_response = YES;
00213 }
00214 else if ( icmp_hdr->icmp_type == ICMP_TIMXCEED )
00215 {
00216 behavior.report( TP_OUT_HOP_INFO, & state.ip_hdr->ip_src, TP_TYPE_TIMXCEED );
00217 state.packet_match = TP_PACKET_MATCH;
00218 }
00219 else if ( icmp_hdr->icmp_type == ICMP_UNREACH )
00220 {
00221 switch ( icmp_hdr->icmp_code )
00222 {
00223 case ICMP_UNREACH_PORT:
00224 behavior.report( TP_OUT_HOP_INFO, & state.ip_hdr->ip_src, TP_TYPE_PORT_UNREACH );
00225 state.packet_match = TP_PACKET_DONE;
00226 state.target_response = YES;
00227 break;
00228 case ICMP_UNREACH_NET:
00229 behavior.report( TP_OUT_HOP_INFO, & state.ip_hdr->ip_src, TP_TYPE_NET_UNREACH );
00230 state.packet_match = TP_PACKET_DONE;
00231 state.target_response = YES;
00232 break;
00233 case ICMP_UNREACH_HOST:
00234 behavior.report( TP_OUT_HOP_INFO, & state.ip_hdr->ip_src, TP_TYPE_HOST_UNREACH );
00235 state.packet_match = TP_PACKET_DONE;
00236 state.target_response = YES;
00237 break;
00238 case ICMP_UNREACH_HOST_PROHIB:
00239 behavior.report( TP_OUT_HOP_INFO, & state.ip_hdr->ip_src, TP_TYPE_HOST_UNREACH );
00240 state.packet_match = TP_PACKET_DONE;
00241 state.target_response = YES;
00242 break;
00243 case ICMP_UNREACH_NET_PROHIB:
00244 behavior.report( TP_OUT_HOP_INFO, & state.ip_hdr->ip_src, TP_TYPE_NET_UNREACH );
00245 state.packet_match = TP_PACKET_DONE;
00246 state.target_response = YES;
00247 break;
00248 case ICMP_UNREACH_FILTER_PROHIB:
00249 behavior.report( TP_OUT_HOP_INFO, & state.ip_hdr->ip_src, TP_TYPE_PROHIB );
00250 state.packet_match = TP_PACKET_DONE;
00251 state.target_response = YES;
00252 break;
00253 default:
00254 break;
00255 }
00256 }
00257 else
00258 {
00259 behavior.report( TP_OUT_HOP_INFO, & state.ip_hdr->ip_src, TP_TYPE_OTHER );
00260 state.packet_match = TP_PACKET_MATCH;
00261 }
00262
00263 return ( state.packet_match == TP_PACKET_NO ) ? 0 : 1;
00264 }
00265
00266
00267
00268
00269
00270
00271 int parse_packet( u_char * raw_packet )
00272 {
00273 struct libnet_802_3_hdr * eth_hdr;
00274 int eth_offset, ipv4_offset;
00275
00276 tp_align_freelist.next = NULL;
00277
00278 if ( strncmp ( behavior.interface, "any", 3 ) == 0 )
00279 eth_offset = LINUX_OFFSET + sizeof(struct libnet_802_3_hdr);
00280 else
00281 eth_offset = sizeof(struct libnet_802_3_hdr);
00282
00283 if ( debug.interface == YES )
00284 printf ( "\ndebug: eth_offset is %d\n", eth_offset );
00285
00286 ipv4_offset = eth_offset + sizeof( struct libnet_ipv4_hdr );
00287
00288
00289
00290
00291
00292 eth_hdr = ( struct libnet_802_3_hdr * ) tp_align ( raw_packet,
00293 0,
00294 sizeof ( struct libnet_802_3_hdr ) );
00295
00296
00297 state.ip_hdr = ( struct libnet_ipv4_hdr * ) tp_align ( raw_packet,
00298 eth_offset,
00299 sizeof ( struct libnet_ipv4_hdr ) );
00300
00301 if ( state.ip_hdr->ip_ttl >= 1 )
00302 state.low_ttl = YES;
00303
00304 if ( debug.recv_buf == YES )
00305 {
00306 printf ( "debug: recv buffer:\n" );
00307 debug_packet ( raw_packet, 80 );
00308 }
00309
00310 state.packet_match = TP_PACKET_NO;
00311
00312
00313
00314 switch( state.ip_hdr->ip_p )
00315 {
00316 case IPPROTO_ICMP:
00317
00318 return parse_icmp_packet ( ( const u_char * ) tp_align ( raw_packet,
00319 ipv4_offset,
00320 sizeof ( struct libnet_icmpv4_hdr ) ) );
00321 break;
00322 case IPPROTO_TCP:
00323
00324 return parse_tcp_packet ( ( const u_char * ) tp_align ( raw_packet,
00325 ipv4_offset,
00326 sizeof ( struct libnet_tcp_hdr ) ) );
00327 break;
00328 case IPPROTO_UDP:
00329
00330 return parse_udp_packet ( ( const u_char * ) tp_align ( raw_packet,
00331 ipv4_offset,
00332 sizeof ( struct libnet_udp_hdr ) ) );
00333 break;
00334 default:
00335 break;
00336 }
00337
00338 return 0;
00339 }
00340
00341
00342
00343
00344
00345 void freelist_cleaner ( void )
00346 {
00347 struct tp_align_ref * ref_ptr, * ref_ptr_last;
00348
00349 for ( ref_ptr = tp_align_freelist.next,
00350 ref_ptr_last = NULL;
00351 ref_ptr->next != NULL;
00352 ref_ptr = ref_ptr->next )
00353 {
00354 if ( debug.memory == YES )
00355 {
00356 printf ( "debug: memory: freeing ref %p\n", ref_ptr->ref );
00357 printf ( "debug: memory: freeing last %p\n", (void *) ref_ptr_last );
00358 }
00359
00360 free ( ref_ptr->ref );
00361 if ( ref_ptr_last != NULL ) { free ( ref_ptr_last ); }
00362 ref_ptr_last = ref_ptr;
00363 }
00364
00365
00366 if ( debug.memory == YES )
00367 {
00368 printf ( "debug: memory: freeing ref %p\n", (void *) ref_ptr->ref );
00369 printf ( "debug: memory: freeing last %p\n", (void *) ref_ptr_last );
00370 }
00371 free ( ref_ptr->ref );
00372 free ( ref_ptr_last );
00373
00374 ref_ptr_last = ref_ptr;
00375 if ( debug.memory == YES )
00376 printf ( "debug: memory: freeing last %p\n", (void *) ref_ptr_last );
00377 free ( ref_ptr_last );
00378 }
00379
00380
00381
00382
00383
00384
00385 int tp_ntol ( int n_order )
00386 {
00387 int tmp = n_order & 0xff;
00388 n_order = n_order >> 8;
00389 tmp = tmp << 8;
00390 n_order = n_order | tmp;
00391
00392 return n_order;
00393 }
00394
00395
00396
00397
00398
00399
00400
00401 int send_tcp_reset ( void )
00402 {
00403
00404 state.tcp_h = libnet_build_tcp(
00405 packet.src_port,
00406 packet.dst_port,
00407 libnet_get_prand ( LIBNET_PRu32 ),
00408 libnet_get_prand(LIBNET_PRu32),
00409 TH_RST & TH_FIN,
00410 1500,
00411 0,
00412 0,
00413 LIBNET_TCP_H + behavior.payload_size,
00414 packet.payload,
00415 behavior.payload_size,
00416 state.packet,
00417 state.tcp_h );
00418
00419 state.ip_h = libnet_build_ipv4(
00420 LIBNET_IPV4_H,
00421 0,
00422 packet.ip_id,
00423 packet.frag_bit,
00424 state.current_hop,
00425 packet.protocol_number,
00426 0,
00427 packet.packed_src,
00428 packet.packed_target,
00429 NULL,
00430 0,
00431 state.packet,
00432 state.ip_h );
00433
00434 if ( libnet_write( state.packet ) == -1 )
00435 {
00436 return 1;
00437 }
00438 return 0;
00439 }
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449