原始套接字

  • 1、原始套接字的概述
    • 什么是原始套接字(SOCK_RAW)
    • 数据包在各个层之间的传输
  • 一、(MAC) 链路层封包格式
  • 二、(IP数据报) 网络层、传输层封包格式
    • 2.1、UDP封包格式
    • 2.2、TCP封包格式
    • 2.3、ICMP封包格式:ping
  • 3、ARP协议
  • 2、创建原始套接字(socket)
  • 案例:数据包的分析
    • 链路层数据格式

1、原始套接字的概述

什么是原始套接字(SOCK_RAW)

1、一种不同于SOCK_STREAM、SOCK_DGRAM的套接字,它实现于系统核心
2、可以接收本机网卡上所有的数据帧(数据包),对于监听网络流量和分析网络数据很有作用
3、开发人员可发送自己组装的数据包到网络上
4、广泛应用于高级网络编程
5、网络专家、黑客通常会用此来编写奇特的网络程序

流式套接字只能收发

TCP协议的数据

数据报套接字只能收发

UDP协议的数据

原始套接字可以收发

1、内核没有处理的数据包,因此要访问其他协议
2、发送的数据需要使用,原始套接字(SOCK_RAW)


ubuntu12.04中描述网络协议结构的文件如下

数据包在各个层之间的传输


在TCP/IP协议栈中的每一层为了能够正确解析出上层的数据包,从而使用一些“协议类型”来标记,详细如下图

组装/拆解udp数据包流程

一、(MAC) 链路层封包格式

二、(IP数据报) 网络层、传输层封包格式

2.1、UDP封包格式

  1. 源端口号:发送方端口号
  2. 目的端口号:接收方端口号
  3. 长度:UDP用户数据报的长度,最小值是8(仅有首部)
  4. 校验和:检测UDP用户数据报在传输中是否有错,有错就丢弃

2.2、TCP封包格式


  1. 源端口号:发送方端口号
  2. 目的端口号:接收方端口号
  3. 序列号:本报文段的数据的第一个字节的序号
  4. 确认序号:期望收到对方下一个报文段的第一个数据字节的序号
  5. 首部长度(数据偏移):TCP报文段的数据起始处距离TCP报文段的起始处有多远,即首部长度。单位:32位,即以4字节为计算单位。
  6. 保留:占6位,保留为今后使用,目前应置为0
  7. 紧急URG: 此位置1,表明紧急指针字段有效,它告诉系统此报文段中有紧急数据,应尽快传送
  8. 确认ACK: 仅当ACK=1时确认号字段才有效,TCP规定,在连接建立后所有传达的报文段都必须把ACK置1
  9. 推送PSH:当两个应用进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即
    就能够收到对方的响应。在这种情况下,TCP就可以使用推送(push)操作,这时,发送方TCP把PSH
    置1,并立即创建一个报文段发送出去,接收方收到PSH=1的报文段,就尽快地(即“推送”向前)交
    付给接收应用进程,而不再等到整个缓存都填满后再向上交付
  10. 复位RST: 用于复位相应的TCP连接
  11. 同步SYN: 仅在三次握手建立TCP连接时有效。当SYN=1而ACK=0时,表明这是一个连接请求报文段,
    对方若同意建立连接,则应在相应的报文段中使用SYN=1和ACK=1.因此,SYN置1就表示这是一个连接请
    求或连接接受报文
  12. 终止FIN:用来释放一个连接。当FIN=1时,表明此报文段的发送方的数据已经发送完毕,并要求释
    放运输连接。
  13. 窗口:指发送本报文段的一方的接收窗口(而不是自己的发送窗口)
  14. 校验和:校验和字段检验的范围包括首部和数据两部分,在计算校验和时需要加上12字节的伪头部
  15. 紧急指针:仅在URG=1时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结束后就是
    普通数据),即指出了紧急数据的末尾在报文中的位置,注意:即使窗口为零时也可发送紧急数据
  16. 选项:长度可变,最长可达40字节,当没有使用选项时,TCP首部长度是20字节

2.3、ICMP封包格式:ping

3、ARP协议

ARP(Address Resolution Protocol,地址解析协议)
1、是TCP/IP协议族中的一个
2、主要用于查询指定ip所对应的的MAC
3、请求方使用广播来发送请求
4、应答方使用单播来回送数据
5、为了在发送数据的时候提高效率在计算中会有一个ARP缓存表,用来暂时存放ip所对应的MAC,
在linux中使用ARP即可查看,
在xp中使用ARP -a


** ARP协议格式:**


1.Dest MAC:目的MAC地址
2.Src MAC:源MAC地址
3.帧类型:0x0806
4.硬件类型:1(以太网)
5.协议类型:0x0800(IP地址)
6.硬件地址长度:6
7.协议地址长度:4
8.OP:1(ARP请求),2(ARP应答),3(RARP请求),4(RARP应答)

2、创建原始套接字(socket)

int socket(PF_PACKET, SOCK_RAW, protocol)
功能:创建链路层的原始套接字
参数:protocol:指定可以接收或发送的数据包类型ETH_P_IP:IPV4数据包ETH_P_ARP:ARP数据包ETH_P_ALL:任何协议类型的数据包
返回值:成功(>0):链路层套接字失败(<0):出错
头文件:#include <sys/socket.h>#include <netinet/ether.h>
#include<stdio.h>
#include<sys/socket.h>
#include<netinet/ether.h>
int main()
{//创建一个链路层 通信的原始套接字int fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));printf("fd = %d\n", fd);close(fd);return 0;
}

注意运行 时加sudo

案例:数据包的分析

链路层数据格式


demo:recvfrom接受链路层帧数据



案例:网络分析器:

#include<stdio.h>
#include<sys/socket.h>
#include<netinet/ether.h>int main()
{//1、 创建一个原始套接字 ETH_P_ALL收发任何数据类型int sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));if(sockfd < 0){perror("socket");return 0;}printf("sockfd = %d\n", sockfd);//2、使用recvfrom接受网络数据 数据很多while(1){//定义buf存放帧数据 大小1500 unsigned charunsigned char buf[1500]="";int len = recvfrom(sockfd, buf, sizeof(buf),0,NULL,NULL);printf("len = %d\n", len);//buf不要用%s遍历 帧数大多都是不识别的ASCII值  有太多的0x00//printf("buf=%s\n",buf);//sleep(1);//别sleep会丢失数据//解析buf-->mac头信息-->必须明白mac头的结构//1、mac头部:目的mac(6B) 源mac(6B) 类型(2B)//[mac][ip][tcp/udp][data] ff:ff:ff:ff:ff:ffchar src_mac[18]="";char dst_mac[18]="";sprintf(dst_mac,"%02x:%02x:%02x:%02x:%02x:%02x",\buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]);sprintf(src_mac,"%02x:%02x:%02x:%02x:%02x:%02x",\buf[0+6],buf[1+6],buf[2+6],buf[3+6],buf[4+6],buf[5+6]);printf("%s--->%s\n", src_mac, dst_mac);//判断mac头部中协议类型 0x0800 IP  0x0806 ARP 0x8035 RARPunsigned short mac_type = ntohs(*(unsigned short *)(buf+12));if( mac_type == 0x0800 ){printf("mac_type = %#x IP报文\n",mac_type);//2、分析IP头部unsigned char *ip_addr = buf+14;//+14跳过mac头//ip_addr跳到源IP的起始位置ip_addr += 12;char src_ip[16]="";char dst_ip[16]="";sprintf(src_ip,"%d.%d.%d.%d", \ip_addr[0],ip_addr[1],ip_addr[2],ip_addr[3]);ip_addr += 4;sprintf(dst_ip,"%d.%d.%d.%d", \ip_addr[0],ip_addr[1],ip_addr[2],ip_addr[3]);printf("%s--->%s\n",src_ip,dst_ip);//判断完成网路层的上一层协议类型ip_addr = buf+14;unsigned char *ip_type = ip_addr +9;if(*ip_type == 1){printf("ICMP报文\n");}  else if(*ip_type == 2){printf("IGMP报文\n");}else if(*ip_type == 6){printf("TCP报文\n");ip_addr = buf+14;//ip报文起始位置int ip_head_len = (*ip_addr&0x0f)*4;//提取ip报文的头部长度unsigned char *tcp_addr = buf+14+ip_head_len;unsigned src_port = ntohs(*(unsigned short *)tcp_addr);unsigned dst_port = ntohs(*(unsigned short *)(tcp_addr+2));printf("%hu--->%hu\n", src_port, dst_port);//调到tcp首部长度的位置unsigned char *tcp_headLen_addr = tcp_addr+12;int tcp_head_len = ((*tcp_headLen_addr>>4)&0x0f)*4; printf("TCP:%s\n", tcp_addr+tcp_head_len);}else if(*ip_type == 17){printf("UDP报文\n");ip_addr = buf+14;//ip报文起始位置int ip_head_len = (*ip_addr&0x0f)*4;//提取ip报文的头部长度unsigned char *udp_addr = buf+14+ip_head_len;unsigned short src_port = ntohs(*(unsigned short *)udp_addr);unsigned short dst_port = ntohs(*(unsigned short *)(udp_addr+2));printf("%hu--->%hu\n", src_port, dst_port);printf("%s\n", udp_addr+8);//应用层数据}}else if(mac_type == 0x0806){printf("mac_type = %#x ARP报文\n",mac_type);}else if(mac_type == 0x8035){printf("mac_type = %#x RARP报文\n",mac_type);}}//关闭套接字close(sockfd);return 0;
}

运行结果:

原始套接字(各种协议的分析)相关推荐

  1. 补充学习——原始套接字中协议结构体

    原始套接字中使用结构体,快速获取数据中字节含义 struct iphdr{#if __BYTE_ORDER==__LITTLE_ENDIANunsigned int inl:4;unsigned in ...

  2. Linux原始套接字实现分析---转

    http://blog.chinaunix.net/uid-27074062-id-3388166.html 本文从IPV4协议栈原始套接字的分类入手,详细介绍了链路层和网络层原始套接字的特点及其内核 ...

  3. linux 原始套接字 绑定网卡,Linux原始套接字实现分析

    之所以要转这篇文章,是因为这篇文章是我看到的同类博客中写得最好的,但非常可惜,这篇博客中只有一篇文章,没有什么收藏价值,故将其原文转载,以供今后学习查阅. 本文从IPV4协议栈原始套接字的分类入手,详 ...

  4. linux 原始套接字实现分析

    目录 1 原始套接字概述 1.1 链路层原始套接字 1.2 网络层原始套接字 1.2.1 接收报文 1.2.2 发送报文 2 原始套接字实现 2.1 原始套接字报文收发流程 2.2  链路层原始套接字 ...

  5. Linux原始套接字学习总结

    Linux网络编程:原始套接字的魔力[上] http://blog.chinaunix.net/uid-23069658-id-3280895.html 基于原始套接字编程        在开发面向连 ...

  6. 网络编程——原始套接字实现原理

    目录 1. 基础知识 1.1.概述 1.2.链路层原始套接字 1.3.网络层原始套接字 2.原始套接字的实现 2.1  原始套接字报文收发流程 2.2链路层原始套接字的实现 2.2.1  套接字创建 ...

  7. 【网络编程】---C++实现原始套接字捕获数据包

    C++实现原始套接字捕获数据包 引言 原始套接字与TCP套接字和UDP套接字的区别 原始套接字编程使用的场合 原始套接字的通信过程 (1)基于原始套接字的数据发送过程 (2)基于原始套接字的数据接收过 ...

  8. 【Linux网络编程】原始套接字实例:MAC 头部报文分析

    通过<Linux网络编程--原始套接字编程>得知,我们可以通过原始套接字以及 recvfrom( ) 可以获取链路层的数据包,那我们接收的链路层数据包到底长什么样的呢? MAC 头部(有线 ...

  9. 利用ICMP协议,使用python原始套接字实现主机存活探测工具

    一.课题概述. 一学期一次的课程设计终于开始了(停课两周,马上放寒假了,哈哈哈哈哈哈...)这次我们课程设计的科目是计算机协议,我们小组抽到的题目是利用ICMP模仿ping命令写一个主机存活探测的工具 ...

最新文章

  1. Hadoop2.6.5集群搭建
  2. RHEL-5搭建SSH服务器
  3. 进fastreboot
  4. 雅客EXCEL(4)-录入数据、超链接阻断、下拉菜单、横列转数列、alt+向下方向键、定位公式
  5. 中国移动云智融合峰会 与您相约揽胜九天
  6. Spring @Configuration
  7. 李笑来登GitHub趋势榜第一,教你自学编程,含37%“硬核鸡汤”
  8. utilities —— 常见宏定义
  9. iOS开发之旧版本Xcode下载
  10. java多线程Thread.sleep方法用法详解
  11. python print文本和数字混合_详解Python中的文本处理
  12. c语言开发 kdj,最全面的KDJ基础知识讲解(3)
  13. msvcr100.dll丢失的解决方法?哪种解决方法方便点
  14. java导出帆软pdf,java后台把fineRepo图表导出pdf格式时发生错误!
  15. 在服务器上如何打开mdf文件,在没sql server数据库状况下怎么打开.mdf文件
  16. 第二届中国(泰州)国际装备高层次人才创新创业大赛
  17. 统计推断——假设检验——简单线性回归分析
  18. bmob云服务器信息推送,FAQ-Bmob后端云
  19. MacOS Big Sur Beta 测评|使用体验|有哪些BUG?|如何安装?|实际体验如何?|WWDC2020
  20. Linux中提示No such file or directory解决方法

热门文章

  1. 成都PMP培训机构有推荐的吗?
  2. python数据类型与传参声明
  3. php瓜分红包,今日头条启动“发财中国年”活动,瓜分10亿红包
  4. 手把手教你怎么用tcgames直播玩刺激战场和全军出击吃鸡手游
  5. 2021 福大 计算机类 转专业
  6. RoboCup 2D足球仿真项目team_logo制作教程
  7. SS7基本信号单元格式
  8. NI cDAQ-9172上的板载输入缓冲大小
  9. NI-VISA手册下载方法
  10. 树莓派中SIM7600G-H 4G DONGLE模块使用记录(一)PPP拨号上网/4G上网