| 发表于:2007-04-30 15:00:241楼 得分:0 |
/*下边实现tcp数据包分析的函数定义tcp_protocol_packet_callback*/ void tcp_protocol_packet_callback(u_char *argument,const struct pcap_pkthdr* packet_header,const u_char* packet_content) { u_char flags; /*标记*/ int header_length; /*头长度*/ u_short source_port; /*源端口*/ u_short destination_port; /*目的端口*/ u_short windows; /*窗口大小*/ u_short urgent_pointer; /*紧急指针*/ u_int sequence; /*序列号*/ u_int acknowledgement; /*确认号*/ u_int16_t checksum; /*检验和*/ tcp_protocol=(struct tcp_header *) (packet_content+14+20); /*获得tcp首部内容*/ source_port =ntohs(tcp_protocol-> tcp_source_port); /*获得源端口号*/ destination_port =ntohs(tcp_protocol-> tcp_destination_port); /*获得目的端口号*/ header_length =tcp_protocol-> tcp_offset *4; /*获得首部长度*/ sequence =ntohl(tcp_protocol-> tcp_acknowledgement); /*获得序列号*/ acknowledgement =ntohl(tcp_protocol-> tcp_ack); //ack号 windows = ntohs(tcp_protocol-> tcp_windows); urgent_pointer = ntohs(tcp_protocol-> tcp_urgent_pointer); flags = tcp_protocol-> tcp_flags; //flags,发送rst包时值为4 checksum =ntohs (tcp_protocol-> tcp_checksum); printf( "***************tcp protocol (transprot layer )***************\n "); printf( "source port %d\n ",source_port); printf( "destination port %d\n ",destination_port); switch (destination_port) { case 80:printf( "protocol is http ");break; case 21:printf( "protocol is ftp ");break; case 23:printf( "protocol is telnet ");break; case 25:printf( "protocol is smtp ");break; case 110:printf( "protocol is pop3 ");break; default :break; } printf( "sequence number %u \n ",sequence); printf( "acknowledgement number %u \n ",acknowledgement); printf( "header length %d \n ",header_length); printf( "reserved %d \n ",tcp_protocol-> tcp_reserved); printf( "flags: "); if (flags & 0x08) printf( "psh "); if (flags & 0x10) printf( "ack "); if (flags & 0x02) printf( "syn "); if (flags & 0x20) printf( "urg "); if (flags & 0x01) printf( "fin "); if (flags & 0x04) printf( "rst "); printf( "\n "); printf( "windows size :%d \n ",windows); printf( "checksum :%d\n ",checksum); printf( "urgent pointer :%d\n ",urgent_pointer); if(!strcmp(ip_s_addr, "172.29.3.111 "))//本机ip地址 { ip_d_addr=inet_ntoa(ip_protocol-> ip_destination_address); if(!strcmp(ip_d_addr, "202.102.144.56 ")) //要阻断的网页的ip地址 { send_rst_packet();//调用发包函数 } } } /*下边实现ip数据包分析的函数定义*/ void ip_protocol_packet_callback(u_char *argument,const struct pcap_pkthdr* packet_header,const u_char* packet_content) { u_int header_length; /*长度*/ u_int offset; /*偏移*/ u_char tos; /*服务质量*/ u_int16_t checksum; /*校验和*/ ip_protocol=(struct ip_header*) (packet_content+14); /*获得ip数据包的内容去掉以太头部*/ checksum=ntohs(ip_protocol-> ip_checksum); /*获得校验和*/ header_length=ip_protocol-> ip_header_length*4; /*获得长度*/ tos=ip_protocol-> ip_tos; /*获得tos*/ offset=ntohs(ip_protocol-> ip_off); /*获得偏移量*/ printf( "***************ip protocol network layer***************\n \n "); printf( "ip version :%d\n ",ip_protocol-> ip_version); printf( "header length :%d\n ",header_length); printf( "tos :%d\n ",tos); printf( "total length:%d\n ",ntohs(ip_protocol-> ip_length));/*获得总长度*/ printf( "identification:%d\n ",ntohs(ip_protocol-> ip_id)); /*获得标识*/ printf( "offset:%d\n ",(offset&0x1fff)*8); /**/ printf( "ttl:%d\n ",ip_protocol-> ip_ttl); /*获得ttl*/ printf( "protocol:%d\n ",ip_protocol-> ip_protocol); /*获得协议类型*/ printf( "header checksum:%d\n ",checksum); printf( "source address:%s\n ",inet_ntoa(ip_protocol-> ip_source_address)); /* 获得源ip地址*/ printf( "destinastion address :%s\n ",inet_ntoa(ip_protocol-> ip_destination_address)); /*获得目的ip地址*/ ip_s_addr=inet_ntoa(ip_protocol-> ip_source_address); switch(ip_protocol-> ip_protocol) { case 6 :printf( "the transport layer protocol is tcp#####################################\n "); tcp_protocol_packet_callback(argument,packet_header,packet_content); break; /*协议类型是6代表tcp*/ case 17:printf( "the transport layer protocol is udp\n ");break;/*17代表udp*/ case 1:printf( "the transport layer protocol is icmp\n ");break;/*代表icmp*/ case 2:printf( "the transport layer protocol is igmp\n ");break;/*代表igmp*/ default :break; } } void ethernet_protocol_packet_callback(u_char *argument,const struct pcap_pkthdr *packet_header,const u_char* packet_content) { u_short ethernet_type; /*以太网协议类型*/ u_char *mac_string; static int packet_number=1; printf( "*******************************************************************************\n "); printf( "the %d ip packet is captured,\n ",packet_number); printf( "**********ethernet protocol (link layer)*******************\n "); ethernet_protocol =(struct ethernet_header *) packet_content; /*获得一太网协议数据内容*/ printf( "ethernet type is :\n "); ethernet_type=ntohs(ethernet_protocol-> ether_type); /*获得以太网类型*/ printf( "%04x\n ",ethernet_type); switch(ethernet_type) /*判断以太网类型的值*/ { case 0x0800 : printf( "the network layer is ip protocol\n ");break; case 0x0806 : printf( "the network layer is arp protocol\n ");break; case 0x8035 : printf( "the network layer is rarp protocol\n ");break; default: break; } printf( "mac souce address is :\n "); mac_string=ethernet_protocol-> ether_shost; printf( "%02x:%02x:%02x:%02x:%02x:%02x:\n ",*mac_string,*(mac_string+1),*(mac_string+2),*(mac_string+3),*(mac_string+4),*(mac_string+5)); /*获得以太网地址*/ printf( "mac destination address is :\n "); mac_string=ethernet_protocol-> ether_dhost; printf( "%02x:%02x:%02x:%02x:%02x:%02x:\n ",*mac_string,*(mac_string+1),*(mac_string+2),*(mac_string+3),*(mac_string+4),*(mac_string+5)); /*获得目的端口地址*/ switch (ethernet_type) {case 0x0800: ip_protocol_packet_callback(argument,packet_header,packet_content);break; /*如果上层是ip协议,就调用分析ip协议的函数对ip包进行分析*/ default :break; } packet_number++; } //主函数 main() { pcap_if_t *alldevs; pcap_if_t *d; int inum=0; int i=0; pcap_t *adhandle; char errbuf[pcap_errbuf_size]; /* 获得网卡的列表 */ if (pcap_findalldevs(&alldevs, errbuf) == -1) { fprintf(stderr, "error in pcap_findalldevs: %s\n ", errbuf); exit(1); } /* 打开选择的网卡 */ d=alldevs; adhandle= pcap_open_live(d-> name, /* 设备名称*/ 65536, /* portion of the packet to capture.*/ /* 65536 grants that the whole packet will be captured on allthe macs.*/ 1, /* 混杂模式*/ 1000, /* 读超时为1秒*/ errbuf /* error buffer*/ ) ; /* at this point, we don 't need any more the device list. free it */ pcap_freealldevs(alldevs); /* 开始捕获包 */ pcap_loop(adhandle, 0, ethernet_protocol_packet_callback, null); return 0; } | | |
|