您的位置:首页 > 其它

IP数据包分析与解析

2012-11-15 15:08 274 查看
版权信息:

本文来自internet,转载这里供网络编程爱好者学习和研究使用,请尊重作者的劳动成果。未经授权而在商业上使用原作者的文章属侵权行为,后果由使用者自负,本人不承担任何法律责任。


IP数据包分析与解析

#include "pcap.h"

#include "stdio.h"
/*下边是以太网的协议格式 */
struct ethernet_header

{

u_int8_t ether_dhost[6]; /*目的以太地址*/

u_int8_t ether_shost[6]; /*源以太网地址*/

u_int16_t ether_type; /*以太网类型*/

};

/*ip地址格式*/

typedef u_int32_t in_addr_t;

//struct in_addr

//{

// in_addr_t s_addr;

//};
struct ip_header

{

#ifdef WORKS_BIGENDIAN

u_int8_t ip_version:4, /*version:4*/

ip_header_length:4; /*IP协议首部长度*/

#else

u_int8_t ip_header_length:4,

ip_version:4;

#endif

u_int8_t ip_tos; /*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_source_address; /*源IP*/

struct in_addr ip_destination_address; /*目的IP*/

};
/*关于tcp头部的定义*/

struct tcp_header

{

u_int16_t tcp_source_port;

u_int16_t tcp_destination_port;

u_int32_t tcp_acknowledgement;

u_int32_t tcp_ack;
#ifdef WORDS_BIGENDIAN
u_int8_t tcp_offset:4 ,

tcp_reserved:4;

#else

u_int8_t tcp_reserved:4,

tcp_offset:4;

#endif

u_int8_t tcp_flags;

u_int16_t tcp_windows;

u_int16_t tcp_checksum;

u_int16_t tcp_urgent_pointer;

};
/*下边实现tcp数据包分析的函数定义tcp_protocol_packet_callback*/

void tcp_protocol_packet_callback(u_char *argument,const struct pcap_pkthdr*
packet_header,const u_char* packet_content)
{

struct tcp_header *tcp_protocol ; /*tcp协议变量*/
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);
windows = ntohs(tcp_protocol->tcp_windows);
urgent_pointer = ntohs(tcp_protocol->tcp_urgent_pointer);
flags = tcp_protocol->tcp_flags;
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);
}

/*下边实现IP数据包分析的函数定义ethernet_protocol_packet_callback*/

void ip_protocol_packet_callback(u_char *argument,const struct pcap_pkthdr*
packet_header,const u_char* packet_content)

{

struct ip_header *ip_protocol; /*ip协议变量*/

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地址*/
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; /*以太网协议类型*/
struct ethernet_header *ethernet_protocol; /*以太网协议变量*/
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);

}

/* 打印网卡信息 */

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 LibPcap 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");

/* Free the device list */

pcap_freealldevs(alldevs);

return -1;

}

/* 找到要选择的网卡结构 */

for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);

/* 打开选择的网卡 */

if ( (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*/

) ) == NULL)

{

fprintf(stderr,"/nUnable to open the adapter. %s is not supported by LibPcap/n");

/* Free the device list */

pcap_freealldevs(alldevs);

return -1;

}

printf("/nlistening on %s.../n", d->description);

/* 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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: