08_原始套接字

news2024/11/24 1:55:38

知识点1【原始套接字概述】

 1、UDP封包格式

​IP封包格式:

Ethernet封包格式 

TCP封包格式: 

 ICMP封包格式:ping

知识点2【数据包的分析】

 案例:网络分析器:

知识点2【混杂模式】接受数据(了解) 

知识点3【原始套接字发送数据】sendto 

1、本机的接口地址结构

2、获取我们的本地接口

知识点4【案例:扫描mac地址 ARP】

 ARP协议格式:

知识点1【原始套接字概述】

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

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

组装/拆解udp数据包流程

 1、UDP封包格式

IP封包格式:

Ethernet封包格式 

TCP封包格式: 

 ICMP封包格式:ping

知识点2【数据包的分析】

链路层数据格式

 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 char
		unsigned 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:ff
		char 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 RARP
		unsigned 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;
}

 运行结果:

 

知识点2【混杂模式】接受数据(了解) 

linux下设置

1、设置混杂模式:ifconfig eth0 promisc

2、取消混杂模式:ifconfig eth0 -promisc

linux下通过程序设置网卡混杂模式: 

知识点3【原始套接字发送数据】sendto 

sendto(sock_raw_fd, msg, msg_len, 0,(struct sockaddr*)&sll, sizeof(sll));
注意:
1、sock_raw_fd:原始套接字
2、msg:发送的消息(封装好的协议数据)
3、sll:本机网络接口,指发送的数据应该从本机的哪个网卡出去,而不是以前的目的地址
想一想:
如何定义sll?

原始套接字:组帧数据报文----->从本机的哪块网卡sendto发出去

1、本机的接口地址结构

#include <netpacket/packet.h>
struct sockaddr_ll sll;

只需要对sll.sll_ifindex赋值,就可使用

sll.sll_ifindex=本地接口;//关键就是本地接口如何获得
sendto(sock_raw_fd, msg, msg_len, 0,(struct sockaddr*)&sll, sizeof(sll));

2、获取我们的本地接口

通过ioctl来获取网络接口地址

struct ifreq:#include <net/if.h>
IFNAMSIZ 16

 ioctl参数对照表:

知识点4【案例:扫描mac地址 ARP】

ARP概述

ARP(Address Resolution Protocol,地址解析协议)

1、是TCP/IP协议族中的一个

2、主要用于查询指定ip所对应的的MAC

3、请求方使用广播来发送请求

4、应答方使用单播来回送数据

5、为了在发送数据的时候提高效率在计算中会有一个ARP缓存表,用来暂时存放ip所对应的MAC,在linux中使用ARP即可查看,在xp中使用ARP -a

在linux与xp系统下查看ARP的方式:

以机器A获取机器B的MAC为例:

 ARP协议格式:

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/21009.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

win11+WSL2安装visdom

win11WSL2安装visdom环境配置下载visdom小小的修改运行visdom环境配置 Win11WSL2Ubuntu-18.04 下载visdom pip install visdom pip install --upgrade visdom conda install -c conda-forge visdom 小小的修改 \home\grass\miniconda3\envs\torch\lib\python3.8\site-pack…

[一篇读懂]C语言九讲:线性表应用

[一篇读懂]C语言九讲&#xff1a;线性表应用1. 与408关联解析及本节内容介绍1 与408关联解析2 本节内容介绍2. 线性表的顺序表示原理解析1 线性表线性表的定义线性表的特点2 线性表的顺序表示顺序表的定义顺序表优缺点顺序表插入操作顺序表删除操作动态分配3. 顺序表的初始化及…

微服务系列之单体架构

随笔 终于迎来了“微服务、云原生”系列文章&#xff0c;这个系列的文章的更新速度博主无法保证能够每个星期一篇&#xff0c;因为这个系列的难度比以往系列都要高&#xff08;以往的系列就没有保证一个星期一更&#xff09;。但是长时间不去写文章&#xff0c;自己可能会慢慢…

Keepalived+LVS部署

目录 一、环境准备 二、实验拓扑 三、部署LVS DR环境 四、LVS服务器配置keepalived 1、安装keepalived 2、修改lvs1服务器keepalived配置 3、修改lvs2服务器keepalived配置 五、客户端测试 1、负责均衡测试 2、LVS服务器高可用测试 一、环境准备 准备4台centos服务器…

学习日记(单元测试、反射、注解、动态代理)

文章目录学习日记&#xff08;单元测试、反射、注解、动态代理&#xff09;一、单元测试1. 单元测试实践2. JUnit 常用注解二、反射1. 反射获取类对象2. 反射获取构造器对象3. 反射获取成员变量对象4. 反射获取成员方法对象三、反射的作用举例1. 绕过编译阶段为集合添加数据2. …

基于生物地理学的优化算法(BBO)用于训练多层感知器(MLP)【多种算法进行比较】(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

java中的BigDecimal使用

文章目录1、什么是BigDecimal&#xff1f;2、为什么使用BigDecimal&#xff1f;3、如何使用BigDecimal&#xff1f;&#xff08;1&#xff09;BigDecimal初始化赋值&#xff08;2&#xff09;加减乘除运算&#xff08;3&#xff09;BigDecimal保留两位小数及舍入模式&#xff0…

WFP实现侧边栏导航菜单

菜单导航功能实现&#xff0c;常规的管理系统应该常用&#xff0c;左侧显示菜单条目&#xff0c;点击菜单&#xff0c;右侧切换不同的业务用户控件。 常用菜单可以采用TreeView树形控件特定样式实现 &#xff0c;本文介绍的是使用ExpanderListView的组合形式实现的导航菜单&am…

算法day24|理论基础77

详细布置 理论基础 什么是回溯法&#xff1a;递归函数下面通常有回溯法 它使用的地方&#xff1a;组合&#xff0c;切割&#xff0c;子集&#xff0c;排列&#xff0c;棋盘问题&#xff08;N皇后&#xff0c;解数独&#xff09; 回溯算法的模板: void backtracking(参数)&…

微型计算机基础

微型计算机常用术语 位&#xff08;bit&#xff09;&#xff1a;计算机所能表示的最基本&#xff0c;最小的数据单元。1个二进制位有两种状态0和1 通常情况下0表示低电平&#xff08;接地&#xff09;&#xff0c;1表示高电平接电源&#xff08;VCC&#xff09; 字节&#xff0…

MATLAB 矩阵处理及多项式计算

一、实验目的 &#xff08;1&#xff09;掌握生成特殊矩阵以及矩阵处理的方法 &#xff08;2&#xff09;掌握数据统计和分析的方法 &#xff08;3&#xff09;掌握多项式的常用计算 二、实验原理与实验设备 原理&#xff1a;计算机编程相关知识技能和MATLAB软件编译环境 …

c++——map和set的封装

注&#xff1a;该封装基于前面博客已实现红黑树&#xff0c;map和set封装并不难&#xff0c;主要还是对红黑树的理解 目录 一. 改造红黑树 1. 改变节点的定义&#xff0c;使用更高维度的泛型 2. 红黑树追加迭代器的实现 1. 红黑树迭代器的构造函数和基本框架 2. begin()和e…

2.4、编码与调制

2.4、编码与调制 在计算机网络中。计算机需要处理和传输用户的文字&#xff0c;图片&#xff0c;音频和视频。它们可以统称为消息。 数据是运送消息的实体。 计算机中的网卡将比特 000 和 111&#xff0c;变换成相应的电信号发送到网线。 也就是说&#xff0c;信号是数据的…

[附源码]java毕业设计网络学习平台

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

LeetCode力扣刷题——更加复杂的数据结构

更加复杂的数据结构 一、引言 目前为止&#xff0c;我们接触了大量的数据结构&#xff0c;包括利用指针实现的三剑客和 C 自带的 STL 等。 对于一些题目&#xff0c;我们不仅需要利用多个数据结果解决问题&#xff0c;还需要把这些数据结构进行嵌套和联 动&#xff0c;进行更为…

五.STM32F030C8T6 MCU开发之RTC模块基础例程

五.STM32F030C8T6 MCU开发之RTC模块基础例程 文章目录五.STM32F030C8T6 MCU开发之RTC模块基础例程0.总体功能概述1.RTC硬件介绍1.1日历的功能1.2 闹钟输出1.3 入侵检测1.4 时间戳事件检测2.RTC软件配置2.1.RTC 模块初始化配置2.2 RTC 开始时间配置2.2.1RTC 年月日 时分秒配置2.…

_linux 进程间通信(管道)

文章目录1. 进程间通信目的2. 进程间通信发展3. 进程间通信分类4. 管道1. 进程间通信目的 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程资源共享&#xff1a;多个进程之间共享同样的资源。通知事件&#xff1a;一个进程需要向另一个或一组进程发送消息&#x…

【English】十大词性之介词

介词 文章目录介词前言一、方位介词1.1 某地1.2 里里外外1.3 上上下下1.4 前前后后1.5 ....中间1.6 ...穿越1.7 ...树上1.8 在...墙上1.9 旁边(距离远近区分)二、时间介词三、方式介词四、易混淆介词4.1 制成4.2 交通工具4.3 除了总结前言 介词是表示名词、代词与句子中其它词…

02Java线程模型

1. 操作系统线程 无论使用何种编程语言编写多线程程序&#xff0c;最终都是通过调用操作系统的线程来执行任务。线程是CPU调度的最小执行单元。 线程有多种实现方式&#xff0c;常见的有&#xff1a;内核线程、用户线程、混合线程。 不同线程模型的主要区别在于线程的调度方不…

【Ubuntu】配置ubuntu网络

配置ubuntu网络 一、三种虚拟网络介绍二、 配置ubuntu系统使用桥接模式连接外网三、通过NAT模式让ubuntu系统连接外网四、常见问题1.解决ubuntu系统没有网络图标一、三种虚拟网络介绍 VMnet0 : 桥接模式,选中桥接模式之后,可以将VMnet0桥接到对应的物理网卡之上, 默认选中自…