linux c arp协议分析三 - 捕捉并分析tcp包
来源:互联网 发布:棋牌源码 编辑:程序博客网 时间:2024/05/16 09:06
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <netpacket/packet.h>#include <net/ethernet.h>#include <arpa/inet.h>//以太网的最大传输单元为1500#define MTU 1500struct ethernet_header{unsigned char mac_target[ETH_ALEN];unsigned char mac_source[ETH_ALEN];unsigned short ether_type;};struct ip_header{//ip头部长度,及ip协议版本//说明首部有多少32位字长,如果是5则表示有5个32位字长,也就是20个字节unsigned char header_len:4,version:4;//服务类型unsigned char st_routine:3,st_nd:1,st_nt:1,st_nr:1,st_ectbit:1,st_ce:1;unsigned short total_len;unsigned short iden;unsigned short flags;unsigned char time_to_live;unsigned char protocal;unsigned short hc;unsigned char source_ip[4];unsigned char target_ip[4];};struct tcp_header{unsigned short int source_port;unsigned short int target_port;unsigned int seqnum;unsigned int acknum;unsigned char reserve:4,//tcp头部的偏移,以4字节为单位,为8时表示偏移量是8*4=32个字节dataoffset:4;unsigned char flags;unsigned short int win;unsigned short int checksum;unsigned short int up;};void die(const char*pre);void print_ethdr(struct ethernet_header **ppethdr);void print_iphdr(struct ip_header **ppiphdr);void print_tcphdr(struct tcp_header **pptcphdr);int main(void){int sfd, len;struct sockaddr_ll sl;struct ethernet_header *pethdr;struct ip_header *piphdr = 0;struct tcp_header *ptcphdr = 0;char buf[MTU];sfd = socket(AF_PACKET, SOCK_RAW, htons(ETHERTYPE_IP));if(-1 == sfd){die("socket");}memset(&sl, 0, sizeof(sl));sl.sll_family = AF_PACKET;//sl.sll_protocol = htons(ETH_P_ALL);//sl.sll_ifindex = IFF_BROADCAST;if(-1 == bind(sfd, (sockaddr*)&sl, sizeof(sl))){die("bind");}while(1){len = recv(sfd, buf, MTU, 0);if(!len){perror("recv");continue;}//获得ethernet_header的指针ethernet_header *pethdr = (ethernet_header *)&buf;print_ethdr(&pethdr);//获得ip_header的指针piphdr = (ip_header*) ( (char*)pethdr + sizeof(ethernet_header) );print_iphdr(&piphdr);//检测是否为IP协议if(0x6 != piphdr->protocal)continue;//获得tcp_header的指针int optlen = piphdr->header_len > 5 ? 4 : 0;ptcphdr = (tcp_header*) ( (char*)piphdr + sizeof(ip_header) + optlen);print_tcphdr(&ptcphdr);//获取数据区指针//数据区长度int datalen = ntohs(piphdr->total_len) - piphdr->header_len * 4 - ptcphdr->dataoffset * 4;char *pbuf = new char[datalen];//数据区首字节指针char *pdata = (char*) ( (char*)ptcphdr + ptcphdr->dataoffset * 4);memcpy(pbuf, pdata, datalen);printf("---------------------------data begin----------------------------\n");printf("data = %s\n", pbuf);printf("---------------------------data end------------------------------\n");}return 0;}void die(const char*pre){perror(pre);exit(1);}void print_ethdr(struct ethernet_header **ppethdr){int i;struct ethernet_header *pethdr = *ppethdr;printf("---------------------------ethernet header begin------------------------------\n");for(i = 0; i < ETH_ALEN; i++){printf(i == 0 ? "mac_target = %.2x" : ":%.2x", pethdr->mac_target[i]);}for(i = 0; i < ETH_ALEN; i++){printf(i == 0 ? "\nmac_source = %.2x" : ":%.2x", pethdr->mac_source[i]);}printf("\nether_type = %x\n", ntohs(pethdr->ether_type));}void print_iphdr(struct ip_header **ppiphdr){struct ip_header *piphdr = *ppiphdr;printf("---------------------------ip header begin------------------------------\n");printf("version = %d\n", piphdr->version);printf("header_len = %d\n", piphdr->header_len);printf("source_ip = %s\n", inet_ntoa(*(struct in_addr*)(piphdr->source_ip)));printf("target_ip = %s\n", inet_ntoa(*(struct in_addr*)(piphdr->target_ip)));printf("total_len = %d\n", ntohs(piphdr->total_len));printf("protocal = %d\n", piphdr->protocal);}void print_tcphdr(struct tcp_header **pptcphdr){tcp_header *ptcphdr = *pptcphdr;printf("---------------------------tcp header begin------------------------------\n");printf("source_port = %d\n", ntohs(ptcphdr->source_port));printf("target_port = %d\n", ntohs(ptcphdr->target_port));printf("seqnum = %d\n", ntohs(ptcphdr->seqnum));printf("acknum = %d\n", ntohs(ptcphdr->acknum));printf("dataoffset = %d\n", ptcphdr->dataoffset);}