#include <stdio.h> #include <unistd.h> #include <sys/socket.h> #include <sys/types.h> #include <linux/if_ether.h> #include <arpa/inet.h> //定义常量 #define EPT_IP 0x0800 /* type: IP */ #define EPT_ARP 0x0806 /* type: ARP */ #define EPT_RARP 0x8035 /* type: RARP */ #define ARP_HARDWARE 0x0001 /* Dummy type for 802.3 frames */ #define ARP_REQUEST 0x0001 /* ARP request */ #define ARP_REPLY 0x0002 /* ARP reply */ //定义以太网首部 typedef struct ehhdr { unsigned char eh_dst[6]; /* destination ethernet addrress */ unsigned char eh_src[6]; /* source ethernet addresss */ unsigned short eh_type; /* ethernet pachet type */ }EHHDR, *PEHHDR; //定义以太网arp字段 typedef struct arphdr { //arp首部 unsigned short arp_hrd; /* format of hardware address */ unsigned short arp_pro; /* format of protocol address */ unsigned char arp_hln; /* length of hardware address */ unsigned char arp_pln; /* length of protocol address */ unsigned short arp_op; /* ARP/RARP operation */ unsigned char arp_sha[6]; /* sender hardware address */ unsigned long arp_spa; /* sender protocol address */ unsigned char arp_tha[6]; /* target hardware address */ unsigned long arp_tpa; /* target protocol address */ }ARPHDR, *PARPHDR; //定义整个arp报文包,总长度42字节 typedef struct arpPacket { EHHDR ehhdr; ARPHDR arphdr; } ARPPACKET, *PARPPACKET; typedef struct _iphdr //定义IP首部 { unsigned char h_verlen; //4位首部长度+4位IP版本号 unsigned char tos; //8位服务类型TOS unsigned short total_len; //16位总长度(字节) unsigned short ident; //16位标识 unsigned short frag_and_flags; //3位标志位 unsigned char ttl; //8位生存时间 TTL unsigned char proto; //8位协议 (TCP, UDP 或其他) unsigned short checksum; //16位IP首部校验和 unsigned int sourceIP; //32位源IP地址 unsigned int destIP; //32位目的IP地址 }IP_HEADER; typedef struct _udphdr //定义UDP首部 { unsigned short uh_sport; //16位源端口 unsigned short uh_dport; //16位目的端口 unsigned short uh_len;//16位UDP包长度 unsigned short uh_sum;//16位校验和 }UDP_HEADER; typedef struct _tcphdr //定义TCP首部 { unsigned short th_sport; //16位源端口 unsigned short th_dport; //16位目的端口 unsigned int th_seq; //32位序列号 unsigned int th_ack; //32位确认号 unsigned char th_lenres;//4位首部长度/6位保留字 unsigned char th_flag; //6位标志位 unsigned short th_win; //16位窗口大小 unsigned short th_sum; //16位校验和 unsigned short th_urp; //16位紧急数据偏移量 }TCP_HEADER; typedef struct _icmphdr { unsigned char icmp_type; // 类型 unsigned char icmp_code; // 代码 unsigned short icmp_cksum; //校验和 unsigned short icmp_id; unsigned short icmp_seq; // This is not the std header, but we reserve space for time unsigned short icmp_timestamp; }ICMP_HEADER; void analyseIP(IP_HEADER *ip) { unsigned char* p = (unsigned char*)&ip->sourceIP; if(ip->proto == IPPROTO_TCP) printf("Source IP: %u.%u.%u.%u ",p[0],p[1],p[2],p[3]); p = (unsigned char*)&ip->destIP; if(ip->proto == IPPROTO_TCP) printf("Destination IP: %u.%u.%u.%u\n",p[0],p[1],p[2],p[3]); } void analyseTCP(TCP_HEADER *tcp) { printf("TCP -----\n"); printf("Source port: %u\n", ntohs(tcp->th_sport)); printf("Dest port: %u\n", ntohs(tcp->th_dport)); } void analyseUDP(UDP_HEADER *udp) { //printf("UDP -----\n"); //printf("Source port: %u\n", ntohs(udp->uh_sport)); //printf("Dest port: %u\n", ntohs(udp->uh_dport)); } void analyseICMP(ICMP_HEADER *icmp) { //printf("ICMP -----\n"); //printf("type: %u\n", icmp->icmp_type); //printf("sub code: %u\n", icmp->icmp_code); } class rawsocket { public: int Init() { if((sock=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL)))==-1)return 0; return 1; } int Recv(char *buf,int maxlen) { return recvfrom(sock,buf,maxlen,0,NULL,NULL); } private: int sock; }; #include <string> using namespace std; char toch(unsigned char ch) { if(ch<10)return ch+'0'; else return ch-10+'a'; } string mactostr(unsigned char *mac) { int i; string str=""; for(i=0;i<6;i++) { str+=toch((mac[i]&0xf0)>>4); str+=toch((mac[i]&0x0f)); if(i<5)str+=':'; } return str; } char Buf[2000],*buf; #include<time.h> int main() { int L; int perminute,persecond,tempmin,tempsec; time_t second,minute,now; unsigned short *iptype; IP_HEADER *ip; rawsocket sniffer; if(sniffer.Init()) { second=minute=time(NULL); tempmin=tempsec=0; persecond=perminute=0; while(1) { L=sniffer.Recv(Buf,1518);Buf[L-4]=0; tempsec+=L; tempmin+=L; PEHHDR Pehhdr=(PEHHDR)Buf; if((now=time(NULL))>second) { second=now; persecond=tempsec; tempsec=0; if(now-60>=minute) { perminute=tempmin; minute=now; tempmin=0; } printf("流量每秒%d字节,每分钟%d字节\n",persecond,perminute); } continue; buf=Buf+14; ip = ( IP_HEADER *)(buf); if(ip->proto == IPPROTO_TCP) printf("\n\n\n%s==>%s::%x\n\n",mactostr(Pehhdr->eh_src).c_str(),mactostr(Pehhdr->eh_dst).c_str(),Pehhdr->eh_type); analyseIP(ip); int iplen=(ip->h_verlen&0x0f)*4; if (ip->proto == IPPROTO_TCP) { TCP_HEADER *tcp = (TCP_HEADER *)(buf+iplen); analyseTCP(tcp); int tcpheaderlen=(tcp->th_lenres&0xf0)>>2; printf("%s\n\n",buf+iplen+tcpheaderlen); } else if (ip->proto == IPPROTO_UDP) { UDP_HEADER *udp = (UDP_HEADER *)(buf + iplen); analyseUDP(udp); } else if (ip->proto == IPPROTO_ICMP) { ICMP_HEADER *icmp = (ICMP_HEADER *)(buf + iplen); analyseICMP(icmp); } else if (ip->proto == IPPROTO_IGMP) { //printf("IGMP----\n"); } else { //printf("other protocol! code:%d\n",ip->proto); } } } else printf("init failed\n"); return 0; }