首页 > 编程知识 正文

linux wireshark,python tcp数据分析

时间:2023-05-03 17:16:56 阅读:21418 作者:3306

我们平时使用的网络编程是在APP应用层发送和接收数据的。 每个程序只接收发给自己的数据。 也就是说,每个程序只接收来自该程序绑定到的端口的数据。 在大多数情况下,收到的数据只包含APP应用层的数据。 在某些情况下,可能需要执行较低级别的操作,例如接收本地发送和接收的所有数据或更改标头。

原始套接字允许捕获发送到本机的所有IP数据包,包括IP报头和TCP/UDP/ICMP报头,以及本机接收到的所有帧,包括数据链路层协议报头。 常规套接字无法处理ICMP、IGMP等网络消息,但SOCK_RAW可以。 利用原始套接字,我们可以自己创建IP报头。

有两种原始插座

一个是处理IP层,即其上的数据,通过将套接字的第一个参数指定为AF_INET来创建该套接字。

另一种是通过处理数据链路层或其上的数据,将套接字的第一个参数指定为AF_PACKET来创建此套接字。

AF_INET表示要从网络层获取数据

socket(af_inet,SOCK_RAW,…)

接收包时,表示用户已获取包含IP标头的完整包。 这意味着数据从IP报头开始。

在发送分组时,用户只能发送TCP报头、UDP报头或其他包含传输协议的消息,并且IP报头和以太网帧报头由内核自动封装。 除非设置了IP_HDRINCL的套接字选项。

第二个参数为SOCK_STREAM、SOCK_DGRAM时,表示接收的数据是直接APP的应用层数据。

PF_PACKET指示所获取的数据是来自数据链路层的数据

socket(pf_packet,SOCK_RAW,htos ) eth_p_IP ) )指示在从其获取IPV4的数据链路层帧,即数据中包含以太网帧报头120(8:UDP或20:tcp ) ) )。

ETH_P_IP:在linux/if_ether.h中定义,有关支持的其他协议,请参见此文件。

可以同时使用SOCK_RAW和SOCK_DGRAM参数。 区别在于,使用SOCK_DGRAM接收的数据不包含数据链路层协议标头。

总的来说:

socket(af_inet、SOCK_RAW、IP proto _ TCP|IP proto _ UDP|IP proto _ icmp ) )发送和接收IP分组

能力:该套接字能够接收来自设备的具有协议类型(例如tcp udp icmp )的ip分组

否:接收非本地ip的数据包。 (ip软过滤器丢弃不是本地ip的数据包。 )

否:收到本机发送的数据包

发送时需要自己组织tcp udp icmp等头部。 可以用setsockopt自行包装ip头部

这个插座适合写ping程序

socket(pf_packet,SOCK_RAW|SOCK_DGRAM,htons ) eth _ p _ IP|eth _ p _ ARP () )是

该套接字相对强大,可以接收网卡上的所有数据帧

可以接收发往:本地mac的数据帧

:能够接收从自身设备发射的数据帧(第三个参数需要设定为ETH_P_ALL )。

:可以接收未发送到本地mac的数据帧。 (网卡必须设置为promisc混合模式。 )

协议类型共有四种

ETH_P_ip0x800仅接收发送至本地mac的IP类型的数据帧

ETH_P_arp0x806仅接受去往本地mac的ARP类型的数据帧

ETH_P_RARP0x8035仅接受去往本地mac的rarp类型的数据帧

ETH_P_ALL0x3接收发往本装置mac的所有类型的ip arp rarp的数据帧,以及接收从本装置发送的所有类型的数据帧。 (在混合模式开启的情况下,接收发往非本机mac的数据帧() ) ) ) ) ) ) )。

# includesys/types.h # includesys/socket.h # includesys/ioctl.h # include net/if.h # include string.h # include includenetinet/if _ ether.h # includenetinet/in.htypedefstruct _ iphdr//定义IP标头{unsignedcharh} //4位标头长4位//8位服务类型TOS unsigned short total_len; //16位总长度(字节)统一短整型; //16位标记unsigned short frag_and_flags; //3位标志unsigned char ttl; //8位生存时间TTL unsigned char proto; //8位协议(TCP、UDP或其他)统一短检查程序; //16位IP标头和不一致的int sou

rceIP; //32位源IP地址 unsigned int destIP; //32位目的IP地址 }IP_HEADER; typedef struct _udphdr //定义UDP首部{ unsigned short uh_sport; //16位源端口 unsigned short uh_dport; //16位目的端口 unsigned int uh_len;//16位UDP包长度 unsigned int uh_sum;//16位校验和}UDP_HEADER; typedef struct _tcphdr //定义TCP首部 { unsigned short th_sport; //16位源端口 unsigned short th_dport; //16位目的端口 unsigned int th_seq; //32位序列号 unsigned int th_ack; //32位确认号 unsigned char th_lenres;//4位首部长度/6位保留字 unsigned char th_flag; //6位标志位 unsigned short th_win; //16位窗口大小 unsigned short th_sum; //16位校验和 unsigned short th_urp; //16位紧急数据偏移量}TCP_HEADER; typedef struct _icmphdr { unsigned char icmp_type; unsigned char icmp_code; /* type sub code */ unsigned short icmp_cksum; unsigned short icmp_id; unsigned short icmp_seq; /* This is not the std header, but we reserve space for time */ unsigned short icmp_timestamp; }ICMP_HEADER; void analyseIP(IP_HEADER *ip);void analyseTCP(TCP_HEADER *tcp);void analyseUDP(UDP_HEADER *udp);void analyseICMP(ICMP_HEADER *icmp); int main(void){ int sockfd; IP_HEADER *ip; char buf[10240]; ssize_t n; /* capture ip datagram without ethernet header */ if ((sockfd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)))== -1) { printf("socket error!n"); return 1; } while (1) { n = recv(sockfd, buf, sizeof(buf), 0); if (n == -1) { printf("recv error!n"); break; } else if (n==0) continue; //接收数据不包括数据链路帧头 ip = ( IP_HEADER *)(buf); analyseIP(ip); size_t iplen = (ip->h_verlen&0x0f)*4; TCP_HEADER *tcp = (TCP_HEADER *)(buf +iplen); if (ip->proto == IPPROTO_TCP) { TCP_HEADER *tcp = (TCP_HEADER *)(buf +iplen); analyseTCP(tcp); } else if (ip->proto == IPPROTO_UDP) { UDP_HEADER *udp = (UDP_HEADER *)(buf + iplen); analyseUDP(udp); } else if (ip->proto == IPPROTO_ICMP) { ICMP_HEADER *icmp = (ICMP_HEADER *)(buf + iplen); analyseICMP(icmp); } else if (ip->proto == IPPROTO_IGMP) { printf("IGMP----n"); } else { printf("other protocol!n"); } printf("nn"); } close(sockfd); return 0;} void analyseIP(IP_HEADER *ip){ unsigned char* p = (unsigned char*)&ip->sourceIP; printf("Source IPt: %u.%u.%u.%un",p[0],p[1],p[2],p[3]); p = (unsigned char*)&ip->destIP; printf("Destination IPt: %u.%u.%u.%un",p[0],p[1],p[2],p[3]); } void analyseTCP(TCP_HEADER *tcp){ printf("TCP -----n"); printf("Source port: %un", ntohs(tcp->th_sport)); printf("Dest port: %un", ntohs(tcp->th_dport));} void analyseUDP(UDP_HEADER *udp){ printf("UDP -----n"); printf("Source port: %un", ntohs(udp->uh_sport)); printf("Dest port: %un", ntohs(udp->uh_dport));} void analyseICMP(ICMP_HEADER *icmp){ printf("ICMP -----n"); printf("type: %un", icmp->icmp_type); printf("sub code: %un", icmp->icmp_code);}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。