⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipdumpinlinux.cpp

📁 only in linux 只在linux下使用(由于头文件不同)
💻 CPP
📖 第 1 页 / 共 2 页
字号:



#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <net/ethernet.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#define _FAVOR_BSD
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/if_ether.h>
#include <arpa/inet.h>

#ifdef _linux
#include <linux/sockios.h>
#include <linux/if.h>
#else
#include <sys/ioct1.h>
#include <net/bpf.h>
#include <net/if.h>
#include <fcntl.h>
#endif

#define MAXSIZE 4096		
#define OPTNUM 8
#define ON 1
#define OFF 0

enum{ETHER,ARP,IP,TCP,UDP,ICMP,DUMP,ALL};

#define _linux
int open_bpf(char*ifname);
#endif

void print_ethernet(struct ether_header*eth);
void print_arp(struct ether_arp*arp);
void print_ip(struct ip*ip);
void print_icmp(struct icmp*icmp);
void print_tcp(struct tcphdr*tcp);
void print_udp(struct udphdr*udp);

void dump_packet(unsigned char*buff,int len);

char * mac_ntoa(u_char*d);
char * tcp_ftoa(int flag);
char * ip_ttoa(int flag);
char * ip_ftoa(int flag);
void help(char*cmd);

int main(int argc, char * * argv)
{
	struct ether_header * eth;	/* Ethernet报头的结构体		*/
	struct ether_arp * arp;		/* ARP包的结构体			*/
	struct ip * ip;				/* IP报头的结构体			*/
	struct icmp * icmp;			/* ICMP报头的结构体			*/
	struct tcphdr * tcp;		/* TCP报头的结构体			*/
	struct udphdr * udp;		/* UDP报头的结构体			*/
	int s;						/* 套结字描述符				*/
	int len;					/* 接收到数据的长度			*/
	int c;						/* 使用getopt()所获得的字符	*/
	int disp;					/* 是否在屏幕上显示的标志	*/
	char buff[MAXSIZE];			/* 接收数据缓冲区			*/
	char * p;					/* 显示报头的初始作业用指针	*/
	char * p0;					/* 显示包的初始作业用指针	*/
	char ifname[256]="xl0";		/* FreeBSD的接口名称		*/
	int opt[OPTNUM];			/* 显示可选域的标志			*/	
	extern int optind;			/* getopt()的全局变量		*/
#ifnder_linux
	int bpf_len;				/* 使用BPF接收到的数据		*/
	struct bpf_hdr * bp;		/* BPF报头的结构体			*/
#endif

	/* 显示包的种类的初始值*/
	opt[ETHER]    = OFF;
	opt[ARP]	  = ON;
	opt[IP]       = ON;
	opt[TCP]      = ON;
	opt[UDP]      = ON;
	opt[ICMP]     = ON;
	opt[DUMP]     = OFF;
	opt[ALL]      = OFF;

	/*  命令行可选域的检查	*/
	while((c=getopt(argc,argv,"aei:p:dh"))!=EOF){
		switch(c){
		case'a':					/*all*/
			opt[ALL]=ON;
			break;
		case'i':					/*if name*/
			strcpy(ifname,optarg);
			break;
		case'e':					/*ethernet*/
			opt[ETHER]=ON;
			break;
		case'd':					/*dump*/
			opt[DUMP]=ON;
			break;
		case'p':					/*protocol*/
			opt[ARP]=OFF;
			opt[IP]=OFF;
			opt[TCP]=OFF;
			opt[UDP]=OFF;
			opt[ICMP]=OFF;
			optind- -;
			while(argv[optind]!=NULL&&argv[optind][0]!='-'){
				if(strcmp(argv[optind],"arp")==0)			/*	arp		*/
					opt[ARP]=ON;
				else if(strcmp(argv[optind],"ip")==0)		/*	ip		*/
					opt[IP]=ON;
				else if(strcmp(argv[optind],"tcp")==0)		/*	tcp		*/
					opt[TCP]=ON;
				else if(strcmp(argv[optind],"udp")==0)		/*	udp		*/
					opt[UDP]=ON;
				else if(strcmp(argv[optind],"icmp")==0)		/*	icmp	*/
					opt[ICMP]=ON;
				else if(strcmp(argv[optind],"other")==0)	/*	other	*/
					;
				else{
					help(argv[0]);
					exit(EXIT_FAILURE);
				}
				optind++;
			}
			break;
		case'h':											/*	help	*/
		case'?':
		default:
			help(argv[0]);
			exit(EXIT_FAILURE);
			break;
		}
	}

	if(optind<argc){
		while(optind<argc)
			printf("%s",argv[optind++]);
		printf("\n");
		help(argv[0]);
		exit(EXIT_FAILURE);
	}

#ifdef _ _linux
	if((s=socket(AF_INET,SOCK_PACKET,htons(ETH_P_ALL)))<0){
		perror("socket");
		exit(EXIT_FAILURE);
	}

	if(strcmp(ifname,"xl0")!=0){
		struct sockadrr sa;
		memset(&sa,0,sizeof sa);
		sa.sa_family=AF_INET;
		strcpy(sa.sa_data,ifname);
		if(bimd(s,&sa,sizeof sa)<0){
			perror("bind");
			exit(EXIT_FAILURE);
		}
	}
#else
	if((s=open_bpf(ifname))<0)
		exit(EXIT_FAILURE);
	bpf_len=0;
#endif

	while(1){
#ifndef _linux
		/*	来自BPF的输入*/
		if(bpf_len<=0){
			/*	一次取出多个包*/
			if((bpf_len=read(s,buff,MAXSIZE))<0){
				perror("read");
				exit(EXIT_FAILURE);
			}
			bp=(struct bpf_hdr*)buff;
		}else{
			/*	移动到BPF的下一个包的指针	*/
			bp=(struct bpf_hdr*)((char*)bp+bp->bh_hdrlen+bp->bh_caplen);
			bp=(struct bpf_hdr*)BPF_WORDALIGN((int)bp);
		}
		/*	设置Ethernet报头的初始指针	*/
		p=po=(char*)bp+bp->bh_hdrlen;
		len=bp->bh_caplen;
#ifder DEBUG
		/*	显示BPF报头的结构体*/
		printf("bpf_len=%d,",bpf_len);
		printf("hdrlen=%d,",bp->bh_hdrlen);
		printf("caplen=%d,",bp->bh_caplen);
		printf("datalen=%d\n",bp->bh_datalen);
#endif;
		/*	为了进行下一个while循环的处理	*/
		bpf_len-=BPF_WORDALIGN(bp->bh_hdrlen+bp->bh_caplen);
#else
		/*	来自linux SOCK_PACKET的输入	*/
		if((len=read(s,buff,MAXSIZE))<0){
			perror("read");
			exit(EXIT_FAILURE);
		}
		/*	设置Ethernet报头的初始指针	*/
		p=po=buff;
#endif
		/*
		*	显示包的子程序
		*/
		disp=OFF;	/*	是否在屏幕上输出的标志	*/

		/*	Ethernet报头结构体的设定	*/
		eth=(struct ether_header*)p;
		p=p+sizeof(struct ether_header);

		if(ntohs(eth->ether_type)==ETHERTYPE_ARP){
			if(opt[ARP]==ON){
				if(opt[ETHER]==ON)
					print_ethernet(eth);
				arp=(struct ether_arp*)p;
				print_arp(arp);
				disp=ON;
			}
		}else if (ntohs(eth->ether_type)==ETHERTYPE_IP){
			ip=(struct ip*)p;
			p=p+((int)(ip->ip_hl)<<2);

			if(opt[IP]==ON&&opt[TCP]==OFF&&opt[UDP]==OFF&&opt[ICMP]==OFF){
				if(opt[ETHER]==ON)
					print_ethernet(eth);
				print_ip(ip);
				disp=ON;
			}
			switch(ip->ip_p){
				case IPPROTO_TCP;
				tcp=(struct tcphdr*)p;
				p=p+((int)(tcp->th_off)<<2);
				if(opt[TCP]==ON){
					if(opt[IP]==ON){
						if(opt[ETHER]==ON)
							print_ethernet(eth);
						print_ip(ip);
					}
					print_tcp(tcp);
					disp=ON;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			}
				break;
		case IPPROTO_UDP;
			udp=(struct udphdr * );
			p=p + sizeof(struct udphdr);
			if (opt[UDP]==ON){
				if (opt[IP]==ON){
					if (opt[ENTER]==ON)
						print_ethernet(eth);
					print_ip(ip);
				}
				print_udp(udp);
				disp = ON;
			}
			break;
		case IPPROTO_ICMP;
			icmp=(struct icmp * )p;
			p=p+sizeof(struct udphdr);
			if(opt[ICMP]==ON){
				if (opt[IP]==ON){
					if (opt[ENTER]==ON)
						print_Ethernet(eth);
					print_ip(ip);
				}
				print_icmp(icmp);
				disp = ON;
			}
			break;
		default;
			if (opt[ALL]==ON){
				if (opt[IP]==ON){
					if (opt[ENTER]==ON)
						print_Ethernet(eth);
					print_ip(ip);
				}
				printf("protocol:unknow\n");
				disp = ON;
			}
			break; 
		}
		}else{
			if (opt[ALL]==ON){
				if (opt[ENTER]==ON)
					print_ethernet(eth);
				print("protocol:unknow\n");
				disp = ON;
			}
		}
		if (disp==ON){
			if(opt[DUMP]==ON)
				dump_packet(p0,len);
			printf("\n");
		}
	  }
	return EXIT_SUCCESS;
	}

	/*
	*char *mac_ntoa(u_char * d);
	* 功能
	*   将一个在数组中存储的MAC地址转换为字符串
	* 实际参数
	*   u_char*d;存储MAC地址的区域的初始地址
	* 返回值
	*   变换为一个字符串的MAC地址
	*/
	char *mac_ntoa(u_char * d)
	{
		static char str [50];/*保存变换为字符串的MAC地址*/

		sprintf (str,"%02x:%02x:%02x:%02x:%02x:%02x",d[0],d[1],d[2],d[3],d[4],d[5]);

		return str;
	}

	/*
	* viod print_ethernet(struct ether_header * eth);
	* 功能
	*   显示Ethernet报头
	* 实际参数
	*   struct ether_header*eth;指向Ethernet报头结构体指针
	*返回值
	*   无
	*/
	viod print_ethernet(struct ether_header *eth)
	{
		int type = ntohs (eth->ether_type);//ethernet类型

		if (type <= 1500)
			printf ("IEEE802.3 Ethernet Frame: \n");
		else
			printf("Ethernet Frame: \n");

		printf("+-----------------+----------------"
			"+----------------+\n");
		printf("|Destination MAC Adress:
			"%        17s|\n"mac_ntoa(eth->ether dhost));
		printf("+-----------------+----------------"
			"+----------------+\n");
		printf("|Source MAC Adress:
			"%        17s|\n"mac_ntoa(eth->ether dhost));
		printf("+-----------------------+----------------------"
			"+----------------+\n");
		if (type<1500)
			print("|length:%5u|\n",type);
		else
			printf("|ethernet tpye 0x % 04x |\n",type);
		printf("+----------------+\n");
	}

	/*
	*viod print_arp(struct ether_arp);
	*功能
	*   显示一个ARP包
	*实际参数
	*   struct ether arp*arp;ARP包结构体的指针
	*返回值
	*    无
	*/
	viod print_arp(struct ether_arp * arp);
	{
		static char * arp_operation[]={
			"Unfine",
			"(ARP Request)",
			"(ARPReplay)",
			"(RARP Request)",
			"(RARP Replay)",
		};
		/*显示可选域种类的字符串*/
		int op = ntohs(arp->ea_hdr.ar_op);/*ARP可选域*/

		if (op<=0||5<op)
			op=0;

		printf("protocol:ARP\n");
		printf("+-----------------+-----------------+\n");
		printf("| hadr Type:%2u%-11s| protocol:0x%04x%-9s|\n"),
			ntohs(arp->ea_hdr.ar_hrd),
			(ntohs(arp->ea_hdr.ar_hrd)==ARPHRD_ENTER)?"(Ethernet)":"(Notther)",

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -