NIDS-端口扫描检测初步(抓包部分)

来源:互联网 发布:三维人像数据门系统 编辑:程序博客网 时间:2024/06/15 19:19

原来的代码耦合性太高了,我重构了一下,模块化了。

扫描部分还待扩充


头文件:

config.h

#ifndef lib_pcap_pcap_h#include "pcap.h"#endif#ifndef HAVE_PARAM_H#include "param.h"#endif#ifndef HAVE_CONFIG_H#define HAVE_CONFIG_H/*IPSIZEIP地址的长度MACSIZEMAC地址的长度PORTNUMPORT的个数*/#define IPSIZE 16#define MACSIZE 14#define PORTNUM 65536const int judge_ip_times = 4;// 设置判为可疑的次数const int judge_port_times = 100;const char port_scan_log[] = "port_scan_log.txt";#endif// CONFIG_H


dnmc_packet_data.h

#ifndef HAVE_CONFIG_H#include "config.h"#endif#ifndef HAVE_DNMC_PACKET_DATA_H#define HAVE_DNMC_PACKET_DATA_Htypedef struct protocol_type {int dport_hash[PORTNUM];int dport_last_time[PORTNUM];// ??预想画出特征曲线}protocol_type;typedef struct smac_info {char *dmac;struct protocol_type *pprot_type;struct smac_info* next;}smac_info;typedef struct list_head {char *smac;struct smac_info *psmac_info;struct list_head *next;}list_head;typedef struct rule_list_node {char *name;int mode;int rval;// 0表示不检测,1表示检测struct rule_list_node* next;struct list_head* rule_list;}rule_list_node;#endif// DNMC_PACKET_DATA_H

main.h

#ifndef lib_pcap_pcap_h#include "pcap.h"#endif#ifdef WINDOWS#define unsigned (unsigned int)#endif#ifdef LINUX#define unsigned (unsigned long)#endifchar *packet_filter;// 需要从文件中读取过滤数据参数struct pcap_pkthdr **pool_header;// 数据包池u_char **pool_pkt_data;u_int pool_in_index;u_int pool_out_index;

packet.h

#ifndef HAVE_CONFIG_H#include "config.h"#define HAVE_CONFIG_H#endif#ifndef HAVE_PACKET_H#define HAVE_PACKET_H// 以太网协议格式的定义typedef struct ether_header {u_char dhost[6];// 目标地址u_char shost[6];// 源地址u_short type;// 以太网类型}ether_header;// 用户保存4字节的IP地址typedef struct ip_address {u_char byte1;u_char byte2;u_char byte3;u_char byte4;}ip_address;// 用于保存IPV4的首部typedef struct ip_header {#ifdef WORDS_BIGENDIANu_char ip_version : 4, header_length : 4;#elseu_char header_length : 4, ip_version : 4;#endifu_char ver_ihl;// 版本以及首部长度,各4位u_char tos;// 服务质量u_short tlen;// 总长度u_short identification;// 身份识别u_short offset;// 分组偏移u_char ttl;// 生命周期u_char protocol;// 协议类型u_short checksum;// 包头测验码ip_address saddr;// 源IP地址ip_address daddr;// 目的IP地址u_int op_pad;//可选 填充字段}ip_header;// 保存TCP首部typedef struct tcp_header {u_short sport;u_short dport;u_int sequence;// 序列码u_int ack;// 回复码#ifdef WORDS_BIGENDIANu_char offset : 4, reserved : 4;// 偏移 预留#elseu_char reserved : 4, offset : 4;// 预留 偏移#endifu_char flags;// 标志u_short windows;// 窗口大小u_short checksum;// 校验和u_short urgent_pointer;// 紧急指针}tcp_header;// 保存ICMP数据包typedef struct icmp_header {u_char type;u_char code;u_short checksum;u_short id;u_short sequence;}icmp_header;#endif// PACKET_H

param.h

#ifndef lib_pcap_pcap_h#include "pcap.h"#endif#ifndef HAVE_PARAM_H#define HAVE_PARAM_Hextern char *packet_filter;// 需要从文件中读取过滤数据参数extern struct pcap_pkthdr **pool_header;// 数据包池extern u_char **pool_pkt_data;extern u_int pool_in_index;extern u_int pool_out_index;#endif// PARAM_H

protocol_packet_handle.h

#ifndef HAVE_CONFIG_H#include "config.h"#endifextern void tcp_protocol_packet_handle(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content );extern void udp_protocol_packet_handle(u_char *argument,const struct pcap_pkthdr *packet_header,const u_char *packet_content);extern void icmp_protocol_packet_handle(u_char *argument,const struct pcap_pkthdr *packet_header,const u_char *packet_content);extern void ip_protocol_packet_handle(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content );extern void ethernet_protocol_packet_handle (u_char *argument,const struct pcap_pkthdr *packet_header, const u_char *packet_content);

port_scan.h

#ifndef HAVE_CONFIG_H#include "config.h"#endif#ifndef HAVE_PARAM_H#include "param.h"#endifunsigned _stdcall port_scanThreadFunc(void* pArguments);



源文件:

main.cpp

#include <iostream>#include <process.h>#include "main.h"#include "port_scan.h"#include "protocol_packet_handle.h"#include "dnmc_packet_data.h"#include "packet.h"#include "config.h"#define HAVE_REMOTE#include "remote-ext.h"using namespace std;#pragma comment(lib, "Ws2_32.lib")#pragma comment(lib, "wpcap.lib")int sys_init(pcap_t **adhandle) {pcap_if_t *alldevs;pcap_if_t *d;char errbuf[PCAP_ERRBUF_SIZE];int inum;int i = 0;u_int netmask;char packet_filter[] = "ip and tcp";struct bpf_program fcode;pool_in_index = 0;pool_out_index = 0;// 获得设备列表 pcap_findalldevs_ex()if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) {fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);exit(1);}for(d = alldevs; d; d = d->next) {printf("%d. %s", ++i, d->name);if(d->description) {printf("(%s)\n", d->description);}else {printf("No description available\n");}}if(0 == i) {printf("\nNo interface found!Make sure WinPcap is installed\n");return -1;}printf("Enter the interface number(1-%d):", i);scanf_s("%d", &inum);if(inum < 1 || inum > i) {printf("\nInterface number out of range.\n");pcap_freealldevs(alldevs);return -1;}for(d = alldevs, i = 0; i < inum-1; d=d->next, i++);// 跳转到该设备,打开适配器// 设备名,要捕捉的数据包的部分(65536保证能捕获到不同数据链路层上的每个数据包的全部内容),混杂模式,读取超时时间,错误缓冲池if((*adhandle = pcap_open_live(d->name, 65536, 1, 1000, errbuf)) == NULL) {fprintf(stderr, "\nUnable to open the adapter.%s is not supported by WinPcap\n", errbuf);pcap_freealldevs(alldevs);return -1;}// 检查数据链路层(只考虑了以太网)if(pcap_datalink(*adhandle) != DLT_EN10MB) {fprintf(stderr, "\nThis program works only on Ethernet networks.\n");pcap_freealldevs(alldevs);return -1;}if(d->addresses != NULL) {// 获得接口的第一个地址的掩码netmask = ((struct sockaddr_in*)(d->addresses->netmask))->sin_addr.S_un.S_addr;}else {netmask = 0xffffff;}// 编译过滤器if(pcap_compile(*adhandle, &fcode, packet_filter, 1, netmask) < 0) {fprintf(stderr, "\nUnable to compile the packet filter.Check the syntax\n");pcap_freealldevs(alldevs);return -1;}// 设置过滤器if(pcap_setfilter(*adhandle, &fcode) < 0) {fprintf(stderr, "\nError setting the filter.\n");pcap_freealldevs(alldevs);return -1;}printf("\nlistenting on %s...\n", d->description);pcap_freealldevs(alldevs);return 0;}int sys_start(pcap_t *adhandle) {struct pcap_pkthdr *header;const u_char *pkt_data;int res;struct tm *ltime;time_t local_tv_sec;char timestr[16];ip_header *ih;while((res = pcap_next_ex(adhandle, &header, &pkt_data)) >= 0) {// 请求超时if(0 == res) {continue;}pool_header[pool_in_index] = header;pool_pkt_data[pool_in_index] = const_cast<u_char*>(pkt_data);pool_in_index++;// 分析数据包ethernet_protocol_packet_handle(NULL, header, pkt_data);改为Thread/*// 将时间戳转换成可识别的格式local_tv_sec = header->ts.tv_sec;ltime = localtime(&local_tv_sec);strftime(timestr, sizeof(timestr), "%H:%M:%S", ltime);ih = (ip_header *)(pkt_data + 14); //以太网头部长度// 输出时间和IP信息printf("%s.%.6d len:%d ", timestr, header->ts.tv_usec, header->len);printf("%d.%d.%d.%d -> %d.%d.%d.%d\n",        ih->saddr.byte1,        ih->saddr.byte2,        ih->saddr.byte3,        ih->saddr.byte4,        ih->daddr.byte1,        ih->daddr.byte2,        ih->daddr.byte3,ih->daddr.byte4);*/}if(-1 == res) {printf("Error reading the packet:%s\n", pcap_geterr(adhandle));return -1;}return 0;}int main(int argc, char *argv[]) {pcap_t *adhandle;HANDLE hThread_portscan;unsigned ps_threadID;sys_init(&adhandle);// 系统初始化sys_start(adhandle);// 启动抓包hThread_portscan = (HANDLE)_beginthreadex(NULL, 0, &port_scanThreadFunc, NULL, 0, &ps_threadID);//端口扫描线程return 0;}

protocol_packet_handle.cpp

#ifndef HAVE_CONFIG_H#include "config.h"#endif#ifndef HAVE_PACKET_H#include "packet.h"#endifvoid tcp_protocol_packet_handle(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content ) {struct tcp_header *tcp_protocol;u_short sport;u_short dport;int header_length;u_short windows;u_short urgent_pointer;u_int sequence;u_int acknowledgement;u_short checksum;u_char flags;printf("===========TCP Protocol===========\n");tcp_protocol = (struct tcp_header*)(packet_content + 14 + 20);sport = ntohs(tcp_protocol->sport);dport = ntohs(tcp_protocol->dport);header_length = tcp_protocol->offset * 4;sequence = ntohl(tcp_protocol->sequence);acknowledgement = ntohl(tcp_protocol->ack);windows = ntohs(tcp_protocol->windows);urgent_pointer = ntohs(tcp_protocol->urgent_pointer);flags = tcp_protocol->flags;checksum = ntohs(tcp_protocol->checksum);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");}void udp_protocol_packet_handle(u_char *argument,const struct pcap_pkthdr *packet_header,const u_char *packet_content) {}void icmp_protocol_packet_handle(u_char *argument,const struct pcap_pkthdr *packet_header,const u_char *packet_content) {struct icmp_header *icmp_protocol;icmp_protocol = (struct icmp_header*)(packet_content + 14 + 20);printf("===========ICMP Protocol==========\n");printf("ICMP Type: %d\n", icmp_protocol->type);switch(icmp_protocol->type) {case 8:// 回显请求报文break;case 0:// 回显应答报文break;default:break;}}void ip_protocol_packet_handle(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content ) {struct ip_header *ip_protocol;u_int header_length;u_int offset;u_char tos;u_short checksum;printf("===========IP Protocol===========\n");ip_protocol = (struct ip_header*)(packet_content + 14);header_length = ip_protocol->header_length * 4;checksum = ntohs(ip_protocol->checksum);tos = ip_protocol->tos;offset = ntohs(ip_protocol->offset);switch(ip_protocol->protocol) {case 6:tcp_protocol_packet_handle(argument, packet_header, packet_content);break;case 17:udp_protocol_packet_handle(argument, packet_header, packet_content);break;case 1:icmp_protocol_packet_handle(argument, packet_header, packet_content);break;default:break;}}void ethernet_protocol_packet_handle (u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content) {u_short ethernet_type;// 以太网类型struct ether_header *ethernet_protocol;// 以太网协议变量u_char *mac_string;// 以太网地址ethernet_protocol = (struct ether_header*)packet_content;// 获取以太网数据内容printf("Ethernet type is : \n");ethernet_type = ntohs(ethernet_protocol->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;default:break;}// 获取以太网源地址printf("MAC Source Address is : \n");mac_string = ethernet_protocol->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 Target Address is : \n");mac_string = ethernet_protocol->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_handle(argument, packet_header, packet_content);break;default:break;}}


port_scan.cpp


#ifndef HAVE_CONFIG_H#include "config.h"#endif#ifndef HAVE_PACKET_H#include "packet.h"#endifunsigned _stdcall port_scanThreadFunc(void* pArguments) {return 0;}




原创粉丝点击