linux c arp协议分析三 - 捕捉并分析tcp包

#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 1500 struct 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); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值