计算机网络课程设计——解析IP和ARP数据包

1.课程设计要求:

1)解析IP数据包

课程设计的目的就是设计一个解析IP数据包的程序,并根据这个程序,说明IP数据包的结构及IP协议的相关问题,从而对IP层的工作原理有更好的理解和认识。本设计的目标是捕获网络中的IP数据包,解析数据包的内容,将结果显示在标准输出上,并同时写入日志文件。

2)解析ARP数据包

课程设计的目的是对网络上的ARP数据包进行分析,从而熟悉ARP数据包的结构,对ARP协议有更好的理解和认识。要求编写一程序,获取网络中的ARP数据包,解析数据包的内容,将结果显示在标准输出上,并同时写入日志文件。

2.设计原理

Ip数据报通过winpcap中的过滤器编译设置后可以直接捕获出来,然后按照其首部不同字节数,利用结构体将IP数据报首部内容分别解析出来,并写入日志文件中。IP数据包首部部分如下所示:

在这里插入图片描述

ARP主要作用就是通过IP地址来获取MAC地址。那么怎样获取呢?本机向局域网内主机发送ARP包,ARP包内包含了目的IP,源IP,目的MAC,源MAC,其中目的MAC地址为广播地址,FF-FF-FF-FF-FF-FF,即向局域网内所有主机发送一个ARP请求,那么其他主机收到这个请求之后则会向请求来源返回一个数据包。在这个返回的数据包中包含了自身的MAC地址。那么本机收到这些返回的数据包进行解析之后便会得到局域网内所有主机的MAC地址了。

3.程序设计流程

在这里插入图片描述

4.核心代码:

(1)编译和设置过滤器:

//编译过滤器
    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;
}

(2)解析ARP数据包,并写入日志文档

ofstream fout(argv[1],ios::app); //打开参数二,即日志记录文件,使用ios::app模式,新内容只会写到文件的后面
	int k=1;
    /* 获取数据包 */
    while ((res = pcap_next_ex(adhandle, &header, &pkt_data)) >= 0) {
        if (res == 0)
            /* 超时时间到 */
            continue;

        //解析ARP包
        ArpHeader* arph = (ArpHeader *)(pkt_data + 14);
		printf("----------------------------解析到的第%d个ARP数据包-----------------------------\n",k);
		fout<<"----------------------------解析到的第"<<k<<"个ARP数据包-----------------------------\n";

        //类型 
        printf("报文类型:");
        if (arph->op == 256){
            printf("请求报文\t");
		fout<<"请求报文\t";
		}
        else{
            printf("应答报文\t");
			fout<<"应答报文\t";
		}

        //长度
        printf("长度(B):%d\t", header->len);
		fout<<"长度(B):"<<header->len<<"\t";

        //时间
        /* 将时间戳转换成可识别的格式 */
        local_tv_sec = header->ts.tv_sec;
        ltime = localtime(&local_tv_sec);
        strftime(timestr, sizeof timestr, "%H:%M:%S", ltime);

        printf("时间:%s\n", timestr);
		fout<<"时间:"<<timestr<<"\n";

        //输出源IP
        printf("源IP:");
        for (i = 0; i < 3; i++)
        {
            printf("%d.", arph->sip[i]);
			fout<<int(arph->sip[i]);
        }
        printf("%d\t", arph->sip[3]);
		fout<<"源IP:"<<int(arph->sip[3])<<"\t";

        //输出目的IP
        printf("目的IP:");
        for (i = 0; i < 3; i++)
        {
            printf("%d.", arph->dip[i]);
			fout<<"目的IP:"<<int(arph->dip[i])<<".";

        }
        printf("%d\n", arph->dip[3]);
		fout<<int(arph->dip[2])<<"\n";

        //输出源MAC
        printf("源MAC:");
        for (i = 0; i < 5; i++)
        {
            printf("%02x-", arph->smac[i]);
			fout<<int(arph->smac[i])<<"-";
        }
        printf("%02x\t", arph->smac[5]);
		fout<<"源MAC:"<<int(arph->smac[5])<<"\t";

        //输出目的MAC
        printf("目的MAC:");
        for (i = 0; i < 5; i++)
        {
            printf("%02x-", *(pkt_data + i));
			fout<<int(*(pkt_data + i))<<"-";
        }
        printf("%02x\n", *(pkt_data + 5));
		fout<<"目的MAC:"<<int(*(pkt_data + 5))<<"\n";  
		k++;
    }

    if (res == -1) {   //接收ARP包出错
        printf("Error reading the packets: %s\n", pcap_geterr(adhandle));
        return -1;
    }

    return 0;
}

(3)解析IP数据包:

void ip_protool_packet_callback(u_char *argument,const struct pcap_pkthdr* packet_header,const u_char* packet_content)
{
  struct ip_header *ip_protocol;
  u_int header_length = 0;
  u_int offset;
  u_char tos;
  u_int16_t checksum;
  u_int ip_len;                      //ip首部长度
  u_int ip_version;  
  TcpHeader *tcp;                  //TCP头      
  //MAC首部是14位的,加上14位得到IP协议首部
  ip_protocol = (struct ip_header *) (packet_content+14);
  
  ip_len = (ip_protocol->Version_HLen & 0xf) *4;
  ip_version = ip_protocol->Version_HLen>>4;
  tcp = (TcpHeader *)((u_char *)ip_protocol+ip_len);

  checksum =ntohs(ip_protocol->ip_checksum);
  tos = ip_protocol->ip_tos;
  offset = ntohs(ip_protocol->ip_off);
  printf("---------IP协议---------\n");
  printf("版本号:%d\n", ip_version);
  printf("首部长度:%d\n",ip_len);
  printf("服务质量:%d\n",tos);
  printf("总长度:%d\n",ntohs(ip_protocol->ip_length));
  printf("标识:%d\n",ntohs(ip_protocol->ip_id));
  printf("偏移:%d\n",(offset & 0x1fff) * 8);
  printf("生存时间:%d\n",ip_protocol->ip_ttl);
  printf("协议类型:%d\n",ip_protocol->ip_protocol);
  switch (ip_protocol->ip_protocol)
  {
       case 1: printf("上层协议是ICMP协议\n");break;
       case 2: printf("上层协议是IGMP协议\n");break;
       case 6: printf("上层协议是TCP协议\n");break;
       case 17: printf("上层协议是UDP协议\n");break;
       default:break;
  }

  printf("检验和:%d\n",checksum);
  printf("源IP地址:%s\n", inet_ntoa(ip_protocol->ip_souce_address));
  printf("目的地址:%s\n", inet_ntoa(ip_protocol->ip_destination_address));
  }
}

5.结果及分析

1、运行结果:

解析ARP数据包并写入日志文档:

在这里插入图片描述

日志文档:

在这里插入图片描述

解析IP数据包:

在这里插入图片描述

日志文件:

在这里插入图片描述

6.完整代码如下:

6.1 解析ARP数据包

#include<fstream.h>
#include<conio.h>  //使用_getch()
#include "pcap.h"
#include <string>
#pragma comment(lib,"wpcap.lib")
#pragma comment(lib,"packet.lib")
#pragma comment(lib,"ws2_32.lib")
struct ArpHeader
{
    unsigned short hdtyp;   //硬件类型
    unsigned short protyp;   //协议类型
    unsigned char hdsize;   //硬件地址长度
    unsigned char prosize;   //协议地址长度
    unsigned short op;   //操作类型,ARP请求(1),ARP应答(2),RARP请求(3),RARP应答(4)。
    u_char smac[6];   //源MAC地址
    u_char sip[4];   //源IP地址
    u_char dmac[6];   //目的MAC地址
    u_char dip[4];   //目的IP地址
};

int main(int argc,char *argv[])
{
   /*	if(argc!=2){
		printf("参数不对,应该为exe文件+日志文件名");
		printf("按任意键退出");
		_getch();
	}*/
    pcap_if_t *alldevs;   //所有网络适配器  
    pcap_if_t *d;   //选中的网络适配器 
    int inum;   //选择网络适配器
    int i = 0;   //for循环变量
    pcap_t *adhandle;   //打开网络适配器,捕捉实例,是pcap_open返回的对象
    char errbuf[PCAP_ERRBUF_SIZE];   //错误缓冲区,大小为256
    int res;   //抓包函数pcap_next_ex返回值,1-成功、0:获取报文超时、-1:发生错误、-2: 获取到离线记录文件的最后一个报文
    u_int netmask;    //子网掩码
    //ether proto protocol:如果数据包属于某些以太协议(protocol)类型, 则与此对应的条件表达式为真,协议字段可以是ARP
    char packet_filter[] = "ether proto \\arp";   //要抓取的包的类型,这里是抓取ARP包;
    struct bpf_program fcode;   //pcap_compile所调用的结构体
    struct tm *ltime;   //和时间处理有关的变量 
    char timestr[16];   //和时间处理有关的变量
    time_t local_tv_sec;    //和时间处理有关的变量
    struct pcap_pkthdr *header;   //接收到的数据包的头部
    const u_char *pkt_data;    //接收到的数据包的内容

    /* 获取本机设备列表 */
    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 (i == 0)
    {
        printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
        return -1;
    }

    printf("Enter the interface number (1-%d):", i);
    scanf("%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++);

    /* 打开设备 */
    if ((adhandle = pcap_open(d->name,          // 设备名
        65536,            // 要捕捉的数据包的部分 
                          // 65535保证能捕获到不同数据链路层上的每个数据包的全部内容
        PCAP_OPENFLAG_PROMISCUOUS,    // 混杂模式
        1000,             // 读取超时时间
        NULL,             // 远程机器验证
        errbuf            // 错误缓冲池
        )) == NULL)
    {
        fprintf(stderr, "\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
        /* 释放设列表 */
        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
        /* 如果接口没有地址,那么我们假设一个C类的掩码 */
        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("\nlistening on %s...\n", d->description);
    /* 释放设备列表 */
    pcap_freealldevs(alldevs);

    /*以上代码在WinPcap开发文档中都可以找到,解析ARP包的代码自己编写*/
	ofstream fout(argv[1],ios::app); //打开参数二,即日志记录文件,使用ios::app模式,新内容只会写到文件的后面
	int k=1;
    /* 获取数据包 */
    while ((res = pcap_next_ex(adhandle, &header, &pkt_data)) >= 0) {
        if (res == 0)
            /* 超时时间到 */
            continue;

        //解析ARP包
        ArpHeader* arph = (ArpHeader *)(pkt_data + 14);
		printf("----------------------------解析到的第%d个ARP数据包-----------------------------\n",k);
		fout<<"----------------------------解析到的第"<<k<<"个ARP数据包-----------------------------\n";

        //类型 
        printf("报文类型:");
        if (arph->op == 256){
            printf("请求报文\t");
		fout<<"请求报文\t";
		}
        else{
            printf("应答报文\t");
			fout<<"应答报文\t";
		}

        //长度
        printf("长度(B):%d\t", header->len);
		fout<<"长度(B):"<<header->len<<"\t";

        //时间
        /* 将时间戳转换成可识别的格式 */
        local_tv_sec = header->ts.tv_sec;
        ltime = localtime(&local_tv_sec);
        strftime(timestr, sizeof timestr, "%H:%M:%S", ltime);

        printf("时间:%s\n", timestr);
		fout<<"时间:"<<timestr<<"\n";

        //输出源IP
        printf("源IP:");
        for (i = 0; i < 3; i++)
        {
            printf("%d.", arph->sip[i]);
			fout<<int(arph->sip[i]);
        }
        printf("%d\t", arph->sip[3]);
		fout<<"源IP:"<<int(arph->sip[3])<<"\t";

        //输出目的IP
        printf("目的IP:");
        for (i = 0; i < 3; i++)
        {
            printf("%d.", arph->dip[i]);
			fout<<"目的IP:"<<int(arph->dip[i])<<".";

        }
        printf("%d\n", arph->dip[3]);
		fout<<int(arph->dip[2])<<"\n";

        //输出源MAC
        printf("源MAC:");
        for (i = 0; i < 5; i++)
        {
            printf("%02x-", arph->smac[i]);
			fout<<int(arph->smac[i])<<"-";
        }
        printf("%02x\t", arph->smac[5]);
		fout<<"源MAC:"<<int(arph->smac[5])<<"\t";

        //输出目的MAC
        printf("目的MAC:");
        for (i = 0; i < 5; i++)
        {
            printf("%02x-", *(pkt_data + i));
			fout<<int(*(pkt_data + i))<<"-";
        }
        printf("%02x\n", *(pkt_data + 5));
		fout<<"目的MAC:"<<int(*(pkt_data + 5))<<"\n";  
		k++;
    }

    if (res == -1) {   //接收ARP包出错
        printf("Error reading the packets: %s\n", pcap_geterr(adhandle));
        return -1;
    }

    return 0;
}

解析IP数据包

//捕获网络数据包的C++程序
//可以获得数据包长度、通过以太网类型确定上层协议、源以太网地址和目的以太网地址!
#include "pcap.h"
#include<winsock2.h>
#include<fstream.h>
#pragma comment(lib,"wpcap.lib")
#pragma comment(lib,"packet.lib")
#pragma comment(lib,"ws2_32.lib")
void packet_handler(u_char *param,const struct pcap_pkthdr *header,const u_char *pcap_data);
#define IPTOSBUFFERS 12
void ifprint(pcap_if_t *d);
char * iptos(u_long in);
int i = 0;
/*以下是以太网协议格式*/
struct ether_header
{
  u_int8_t ether_dhost[6]; //目的Mac地址
  u_int8_t ether_shost[6]; //源Mac地址
  u_int16_t ether_type;    //协议类型
};
 
struct ip_header
{
unsigned char Version_HLen;   //版本信息4位 ,头长度4位 1字节
  u_int8_t    ip_tos;
  u_int16_t   ip_length;
  u_int16_t   ip_id;
  u_int16_t   ip_off;
  u_int8_t    ip_ttl;
  u_int8_t    ip_protocol;
  u_int16_t   ip_checksum;
  struct in_addr ip_souce_address;
  struct in_addr ip_destination_address;
};
 
//TCP头部结构体,共20字节
struct TcpHeader
{
    unsigned short SrcPort;                        //源端口号  2字节
    unsigned short DstPort;                        //目的端口号 2字节
    unsigned int SequenceNum;               //序号  4字节
    unsigned int Acknowledgment;         //确认号  4字节
    unsigned char HdrLen;                         //首部长度4位,保留位6位 共10位
    unsigned char Flags;                          //标志位6位
    unsigned short AdvertisedWindow;  //窗口大小16位 2字节
    unsigned short Checksum;                  //校验和16位   2字节
    unsigned short UrgPtr;						  //紧急指针16位   2字节
};
 
void ip_protool_packet_callback(u_char *argument,const struct pcap_pkthdr* packet_header,const u_char* packet_content)
{
  struct ip_header *ip_protocol;
  u_int header_length = 0;
  u_int offset;
  u_char tos;
  u_int16_t checksum;
  u_int ip_len;                      //ip首部长度
  u_int ip_version;  
  TcpHeader *tcp;                  //TCP头          
  //MAC首部是14位的,加上14位得到IP协议首部
  ip_protocol = (struct ip_header *) (packet_content+14);
  
  ip_len = (ip_protocol->Version_HLen & 0xf) *4;
  ip_version = ip_protocol->Version_HLen>>4;
  tcp = (TcpHeader *)((u_char *)ip_protocol+ip_len);

  checksum =ntohs(ip_protocol->ip_checksum);
  tos = ip_protocol->ip_tos;
  offset = ntohs(ip_protocol->ip_off);
  ofstream fout;
  fout.open("解析IP数据包.txt",ios::app); //打开日志记录文件,使用ios::app模式,新内容只会写到文件的后面

  printf("---------IP协议---------\n");
  fout<<"---------IP协议---------\n";
  printf("版本号:%d\n", ip_version);
  fout<<"版本号:"<<ip_version<<"\n";
  printf("首部长度:%d\n",ip_len);
  fout<<"首部长度:"<<ip_len<<"\n";
  printf("服务质量:%d\n",tos);
  fout<<"服务质量:"<<tos<<"\n";
  printf("总长度:%d\n",ntohs(ip_protocol->ip_length));
  fout<<"总长度:"<<ntohs(ip_protocol->ip_length)<<"\n";
  printf("标识:%d\n",ntohs(ip_protocol->ip_id));
  fout<<"标识:"<<ntohs(ip_protocol->ip_id)<<"\n";
  printf("偏移:%d\n",(offset & 0x1fff) * 8);
  int x;
  x=(offset & 0x1fff) * 8;
  fout<<"偏移:"<<x<<"\n";
  printf("生存时间:%d\n",ip_protocol->ip_ttl);
  fout<<"生存时间:"<<ip_protocol->ip_ttl<<"\n";
  printf("协议类型:%d\n",ip_protocol->ip_protocol);
  int y;
  y=ip_protocol->ip_protocol;
  fout<<"协议类型:"<<y<<"\n";
  switch (ip_protocol->ip_protocol)
  {
       case 1: printf("上层协议是ICMP协议\n");break;
       case 2: printf("上层协议是IGMP协议\n");break;
       case 6: printf("上层协议是TCP协议\n");break;
       case 17: printf("上层协议是UDP协议\n");break;
       default:break;
  }

  printf("检验和:%d\n",checksum);
  fout<<"检验和:"<<checksum<<"\n";
  printf("源IP地址:%s\n", inet_ntoa(ip_protocol->ip_souce_address));
  fout<<"源IP地址:"<<inet_ntoa(ip_protocol->ip_souce_address)<<"\n";
  printf("目的地址:%s\n", inet_ntoa(ip_protocol->ip_destination_address));
  fout<<"目的地址:"<<inet_ntoa(ip_protocol->ip_destination_address)<<"\n";
  fout.close();	
}
 
void ethernet_protocol_packet_callback(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;
  static int packet_number = 1;
  
 ethernet_protocol=(struct ether_header*)packet_content;//获得数据包内容
  ethernet_type=ntohs(ethernet_protocol->ether_type);//获得以太网类型
  if(ethernet_type==0x0800)//继续分析IP协议
  {

     ip_protool_packet_callback (argument,packet_header,packet_content);
  }
 // printf("----------------------------------------------\n");
  packet_number++;

}
 
int main(int argc,char *argv[])
// {
//      pcap_t* pcap_handle; //winpcap句柄
//      char error_content[PCAP_ERRBUF_SIZE]; //存储错误信息
//      bpf_u_int32 net_mask; //掩码地址
//      bpf_u_int32 net_ip;  //网络地址
//      char *net_interface;  //网络接口
//      struct bpf_program bpf_filter;  //BPF过滤规则
//      char bpf_filter_string[]="ip"; //过滤规则字符串,只分析IPv4的数据包
//      net_interface=pcap_lookupdev(error_content); //获得网络接口
//      pcap_lookupnet(net_interface,&net_ip,&net_mask,error_content); //获得网络地址和掩码地址
//      pcap_handle=pcap_open_live(net_interface,BUFSIZ,1,0,error_content); //打开网络接口
//      pcap_compile(pcap_handle,&bpf_filter,bpf_filter_string,0,net_ip); //编译过滤规则
//      pcap_setfilter(pcap_handle,&bpf_filter);//设置过滤规则
//      if (pcap_datalink(pcap_handle)!=DLT_EN10MB) //DLT_EN10MB表示以太网
//          return 0;
//      pcap_loop(pcap_handle,10,ethernet_protocol_packet_callback,NULL); //捕获10个数据包进行分析
//      pcap_close(pcap_handle);
//      return 0;
// }
{
	pcap_if_t * alldevs;
	pcap_if_t * d;
	int inum;
	pcap_t * adhandle;
	char errbuf[PCAP_ERRBUF_SIZE];
	/*取得列表*/
	if(pcap_findalldevs(&alldevs,errbuf) == -1)
	{
		exit(1);
	}
	/*输出列表*/
	for(d=alldevs;d != NULL;d=d->next)
	{
		ifprint(d);
	}
	if(i==0)
	{
 
		printf("\nNo interfaces found!Make sure WinPcap is installed.\n");
		char c = getchar();
		return -1;
	}
	printf("Enter the interface number (1-%d):",i);
	scanf("%d",&inum);
	if(inum <1 || inum >i)
	{
		printf("\nInterface number out of range.\n");
		pcap_freealldevs(alldevs);
		char c = getchar();
		return -1;
	}
	
	//转到选择的设备
	for (d = alldevs,i=0;i <inum-1;d=d->next,i++);
	//打开失败
	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");
		pcap_freealldevs(alldevs);
		char c = getchar();
		return -1;
	}
	printf("\nlistening on %s...\n",d->description);
	//释放列表
	pcap_freealldevs(alldevs);
	//开始捕捉
	//pcap_loop(adhandle,0,ip_protool_packet_callback,NULL);
	pcap_loop(adhandle,0,ethernet_protocol_packet_callback,NULL);
	char c = getchar();
	return 0;
}
void ifprint(pcap_if_t *d)
{
	pcap_addr_t *a;
	printf("%d.%s",++i,d->name);
	if(d->description)
	{
		printf("\tDescription:(%s)\n",d->description);
	}else{
		printf("\t(No description available)\n");
	}
	printf("\tLoopback:%s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no");
	for (a=d->addresses;a != NULL;a=a->next)
	{
		printf("\tAddress Family:#%d\n",a->addr->sa_family);
		switch (a->addr->sa_family)
		{
		case AF_INET:
			printf("\tAddress Family Name:AF_INET\n");
			if(a->addr)
			{
				printf("\tAddress:%s\n",iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr));
			}
			if(a->netmask)
			{
				printf("\tNetmask:%s\n",iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));
			}
			if(a->broadaddr)
			{
				printf("\tBroadcast Address:%s\n",iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr));
			}
			if(a->dstaddr)
			{
				printf("\tDestination Address:%s\n",iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));
			}
			break;
		default:
			printf("\tAddressFamilyName:Unknown\n");
			break;
		}
	}
}
char * iptos(u_long in)
{ 
	static char output[IPTOSBUFFERS][3*4+3+1];
	static short which;
	u_char *p; 
	p = (u_char *)&in;
	which=(which+1==IPTOSBUFFERS?0:which+1); 
	sprintf(output[which],"%d.%d.%d.%d",p[0],p[1],p[2],p[3]);
	return output[which];
}
void packet_handler(u_char *param,const struct pcap_pkthdr *header,const u_char *pcap_data)
{
	struct tm * ltime;
	char timestr[16];
	ltime = localtime(&header->ts.tv_sec);
	strftime(timestr,sizeof(timestr),"%H:%M:%S",ltime);
	printf("%s, %.6d len:%d\n",timestr,header->ts.tv_usec,header->len);
}
  • 29
    点赞
  • 253
    收藏
    觉得还不错? 一键收藏
  • 22
    评论
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值