00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 #include "sniff.h"
00026 #include "sniff_private.h"
00027 #include "debug.h"
00028 #include "util.h"
00029 #include <string.h>
00030 #include "nethelp.h"
00031 
00032 errorcode capture_peer_to_buddy_syn(peer_conn_info_t *info) {
00033 
00034         
00035         char errbuf[PCAP_ERRBUF_SIZE]; 
00036         pcap_t *pcap_desc = NULL; 
00037 
00038         
00039         CHECK_NOT_NULL(info,ERROR_NULL_ARG_1);
00040 
00041         
00042 
00043         
00044         CHECK_FAILED(init_packet_capture(&pcap_desc,info->device,1000,
00045                 errbuf, PCAP_ERRBUF_SIZE),ERROR_1);
00046 
00047         
00048         info->buddy_syn.d_addr    = info->buddy.ext_ip;
00049         info->buddy_syn.d_port    = info->buddy.ext_port;
00050         info->buddy_syn.s_addr    = info->peer.ip;
00051         info->buddy_syn.s_port    = info->peer.port;
00052         info->buddy_syn.syn_flag  = FLAG_SET;
00053         info->buddy_syn.ack_flag  = FLAG_UNSET;
00054 
00055         
00056         CHECK_FAILED(find_tcp_packet(pcap_desc, &info->buddy_syn,
00057                 &info->direct_conn_status,NULL,NULL),ERROR_1);
00058 
00059         return SUCCESS;
00060 }
00061 
00062 errorcode capture_flooded_synack(peer_conn_info_t *info) {
00063 
00064         
00065         char errbuf[PCAP_ERRBUF_SIZE];
00066         pcap_t *pcap_desc = NULL;
00067         tcp_packet_info_t skeleton;
00068         unsigned char *payload = NULL;
00069         unsigned long payload_len = 0;
00070 
00071         
00072         CHECK_NOT_NULL(info,ERROR_NULL_ARG_1);
00073 
00074         
00075 
00076         CHECK_FAILED(init_packet_capture(&pcap_desc,info->device,1000,
00077                 errbuf, PCAP_ERRBUF_SIZE), ERROR_1);
00078 
00079         
00080         skeleton.d_addr   = info->peer.ip;
00081         skeleton.d_port   = PORT_UNKNOWN;
00082         skeleton.s_addr   = info->buddy.ext_ip;
00083         skeleton.s_port   = info->buddy.ext_port;
00084         skeleton.ack_flag = FLAG_SET;
00085         skeleton.syn_flag = FLAG_SET;
00086 
00087         
00088         CHECK_FAILED(find_tcp_packet(pcap_desc, &skeleton,
00089                 &info->bday.stop_synack_find,&payload,&payload_len), ERROR_1);
00090 
00091         DEBUG(DBG_BDAY,"DBAY:payload size is %u\n",(unsigned int)payload_len);
00092 
00093         if (payload == NULL)
00094                 return ERROR_1;
00095         if (payload_len != sizeof(port_t))
00096                 return ERROR_2;
00097 
00098         
00099         memcpy(&info->bday.port,payload,sizeof(info->bday.port));
00100         info->bday.port_set = FLAG_SET;
00101 
00102         
00103         close(info->socks.buddy);
00104         CHECK_FAILED(bindSocket(skeleton.d_port,&info->socks.buddy),
00105                 ERROR_CALLED_FUNCTION);
00106 
00107         return SUCCESS;
00108 }
00109 
00110 errorcode init_packet_capture(pcap_t **pcap_desc, char *device, int timeout,
00111                                 char *errbuf, long errbuf_len) {
00112 
00113         
00114         char *filter = "tcp";
00115         struct bpf_program fp;
00116         bpf_u_int32 maskp;
00117         bpf_u_int32 netp;
00118 
00119         
00120         CHECK_NOT_NULL(pcap_desc,ERROR_NULL_ARG_1);
00121         CHECK_NOT_NULL(device,ERROR_NULL_ARG_2);
00122         CHECK_NOT_NULL(errbuf,ERROR_NULL_ARG_4);
00123         CHECK_GREATER_THAN(errbuf_len,PCAP_ERRBUF_SIZE-1,ERROR_ARG_5);
00124 
00125         
00126         if ( pcap_lookupnet(device,&netp,&maskp,errbuf) < 0 ) {
00127                 DEBUG(DBG_SNIFF,
00128                         "SNIFF:did you forget to run this program as root?\n");
00129                 return ERROR_1;
00130         }
00131 
00132         if  ( (*pcap_desc=pcap_open_live(device,BUFSIZ,0,
00133                                         timeout,errbuf)) == NULL )
00134                 return ERROR_2;
00135 
00136         
00137 
00138         if ( pcap_datalink(*pcap_desc) != DLT_EN10MB)
00139                 return ERROR_2;
00140 
00141         
00142         if ( pcap_compile(*pcap_desc,&fp,filter,0,netp) < 0 )
00143                 return ERROR_4;
00144 
00145         
00146         if ( pcap_setfilter(*pcap_desc,&fp) == -1 )
00147                 return ERROR_5;
00148 
00149         
00150         if ( pcap_setnonblock(*pcap_desc,1,errbuf) < 0 )
00151                 return ERROR_6;
00152 
00153         return SUCCESS;
00154 }
00155 
00156 errorcode find_tcp_packet(pcap_t *pcap_desc, tcp_packet_info_t *tcp_skeleton,
00157                         flag_t *break_flag, unsigned char **payload,
00158                         unsigned long *payload_len) {
00159 
00160         
00161         struct pcap_pkthdr hdr;
00162         const u_char *packet;
00163 
00164         
00165         CHECK_NOT_NULL(pcap_desc,ERROR_NULL_ARG_1);
00166         CHECK_NOT_NULL(tcp_skeleton,ERROR_NULL_ARG_2);
00167         CHECK_NOT_NULL(break_flag,ERROR_NULL_ARG_3);
00168 
00169         
00170 
00171         
00172         while ( *break_flag == FLAG_UNSET) {
00173                 
00174 
00175                 if ( (packet=pcap_next(pcap_desc,&hdr)) != NULL) {
00176                         
00177 
00178                         if (!(FAILED(process_packet((unsigned char*) packet,
00179                                         tcp_skeleton,payload,payload_len)))) {
00180                                 return SUCCESS;
00181                         }
00182                 }
00183         }
00184 
00185         DEBUG(DBG_SNIFF,"SNIFF:could not find syn to buddy\n");
00186 
00187         return ERROR_2;
00188 }
00189 
00190 errorcode process_packet(unsigned char*packet,
00191                 tcp_packet_info_t *tcp_skeleton, unsigned char **payload,
00192                 unsigned long *payload_len) {
00193 
00194         
00195         struct ether_header *ether  = NULL; 
00196         struct iphdr        *ip     = NULL; 
00197         struct tcphdr       *tcp    = NULL; 
00198         int ip_hdr_len              = 0;
00199 
00200         
00201         CHECK_NOT_NULL(packet,ERROR_NULL_ARG_1);
00202         CHECK_NOT_NULL(tcp_skeleton,ERROR_NULL_ARG_2);
00203 
00204         
00205 
00206         
00207         ether = (struct ether_header*) (packet);
00208 
00209         ip    = (struct iphdr*) ((char*)ether + sizeof(struct ether_header));
00210         
00211 
00212         ip_hdr_len = 4 * (unsigned int) ip->ihl;
00213 
00214         tcp   = (struct tcphdr*) ( (char*)ip + ip_hdr_len);
00215 
00216         
00217 
00218 
00219 
00220 
00221 
00222 
00223 
00224 
00225 
00226 
00227 
00228 
00229 
00230 
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242         
00243         if (    ( (ip->saddr     !=  tcp_skeleton->s_addr)   &&
00244                   (tcp_skeleton->s_addr != IP_UNKNOWN)     ) ||
00245                 ( (ip->daddr     !=  tcp_skeleton->d_addr)   &&
00246                   (tcp_skeleton->d_addr != IP_UNKNOWN)    ) ||
00247                 ( (tcp->th_sport !=  tcp_skeleton->s_port)   &&
00248                   (tcp_skeleton->s_port != PORT_UNKNOWN)   ) ||
00249                 ( (tcp->th_dport !=  tcp_skeleton->d_port)   &&
00250                   (tcp_skeleton->d_port != PORT_UNKNOWN)   ) ||
00251                 !BOOL_MATCH(tcp->th_flags&TH_ACK,
00252                         (tcp_skeleton->ack_flag==FLAG_SET)) ||
00253                 !BOOL_MATCH(tcp->th_flags&TH_SYN,
00254                         (tcp_skeleton->syn_flag==FLAG_SET))
00255            )  {
00256                 
00257                 return NOT_OK;
00258         }
00259 
00260         DEBUG(DBG_SNIFF,"SNIFF:matched packet\n");
00261 
00262         DEBUG(DBG_SNIFF,"SNIFF:ip.s_addr:  %s\n",DBG_IP(ip->saddr));
00263         DEBUG(DBG_SNIFF,"SNIFF:ip.d_addr:  %s\n",DBG_IP(ip->daddr));
00264         DEBUG(DBG_SNIFF,"SNIFF:tcp.s_port: %d\n",DBG_PORT(tcp->th_sport));
00265         DEBUG(DBG_SNIFF,"SNIFF:tcp.d_port: %d\n",DBG_PORT(tcp->th_dport));
00266 
00267         DEBUG(DBG_SNIFF,"SNIFF:tcp ACK bit is %sset\n",
00268                 (tcp->th_flags&TH_ACK) ? "" : "not ");
00269         DEBUG(DBG_SNIFF,"SNIFF:tcp SYN bit is %sset\n",
00270                 (tcp->th_flags&TH_SYN) ? "" : "not ");
00271 
00272 
00273         
00274         tcp_skeleton->seq_num = tcp->th_seq;
00275         tcp_skeleton->ack_num = tcp->th_ack;
00276         tcp_skeleton->window  = tcp->th_win;
00277 
00278         
00279         tcp_skeleton->s_addr = ip->saddr;
00280         tcp_skeleton->d_addr = ip->daddr;
00281         tcp_skeleton->s_port = tcp->th_sport;
00282         tcp_skeleton->d_port = tcp->th_dport;
00283 
00284         
00285         if (payload != NULL)
00286                 *payload = (unsigned char*) tcp + sizeof(struct tcphdr);
00287         if (payload_len != NULL)
00288                 *payload_len = ntohs(ip->tot_len) - sizeof(struct tcphdr) -
00289                                                         sizeof(struct iphdr);
00290 
00291 
00292         return SUCCESS;
00293 }
00294