Linux内核构造数据包并发送(二)(dev_queue_xmit方式)

2024-02-05 20:38

本文主要是介绍Linux内核构造数据包并发送(二)(dev_queue_xmit方式),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

linux内核太构造数据包的第二种方式就是直接调用dev_queue_xmit函数,将构造完毕的数据包直接发送到网卡驱动。从NF框架来看,该函数的调用是在 POSTROUTING点之后了,也可以理解为直接通过调用二层的发送函数,将三层构造的数据包发送出去。该函数实际上会调用 skb->dev->hard_start_xmit,即对应网卡的驱动函数,将数据包直接发送的出去。 

       很显然,这个工作在二层的函数,发送数据包(数据包在二层的时候准确叫法应该是帧,我们这里是在三层直接调用的,权且还称作数据包)的方式是不需要再查路由了。 

但是,二层发送的时候是需要根据目的MAC来进行的。在第一种方法构造的数据包中,仅仅交换了IP地址,而没有对MAC做任何修改。这样直接调用 dev_queue_xmit是会产生问题的,并且该函数发送的内容应该是从二层头部开始,到数据包的结束。因此,如果三层构造的数据包,想调用该函数直接发送数据包的话,则需要修改数据包的源和目的MAC,并将skb->data指针指向MAC头部,以及skb->len的值也要加上头部的长度方法。以下是可参考的示例代码: 

 

C代码
  1. unsigned char mac_temp[ETH_ALEN] = {0};     
  2.      
  3.  struct ethhdr *mach = NULL;     
  4.      
  5.  ……     
  6.      
  7.  /*code…… 构造数据包的IP即上层协议及数据*/     
  8.      
  9.  ……     
  10.      
  11. /*交换源和目的MAC*/     
  12.      
  13.   mach = (struct ethhdr *)skb->mac.raw;     
  14.      
  15.    memcpy(mac_temp, (unsigned char *)mach->h_dest, ETH_ALEN);     
  16.      
  17.    memcpy(mach->h_dest, (unsigned char *)mach->h_source, ETH_ALEN);     
  18.      
  19.    memcpy(mach->h_source, mac_temp, ETH_ALEN);     
  20.      
  21. /*修改skb->data指针,使其指向MAC头部,并且增加skb->len*/     
  22.      
  23. skb_push(skb , ETH_HLEN);     
  24.      
  25. /*直接调用该函数,将数据包从网卡上发送出去*/     
  26.      
  27. ret = dev_queue_xmit(skb);    
[c] view plain copy print ?
  1. unsigned char mac_temp[ETH_ALEN] = {0};    
  2.     
  3.  struct ethhdr *mach = NULL;    
  4.     
  5.  ……    
  6.     
  7.  /*code…… 构造数据包的IP即上层协议及数据*/    
  8.     
  9.  ……    
  10.     
  11. /*交换源和目的MAC*/    
  12.     
  13.   mach = (struct ethhdr *)skb->mac.raw;    
  14.     
  15.    memcpy(mac_temp, (unsigned char *)mach->h_dest, ETH_ALEN);    
  16.     
  17.    memcpy(mach->h_dest, (unsigned char *)mach->h_source, ETH_ALEN);    
  18.     
  19.    memcpy(mach->h_source, mac_temp, ETH_ALEN);    
  20.     
  21. /*修改skb->data指针,使其指向MAC头部,并且增加skb->len*/    
  22.     
  23. skb_push(skb , ETH_HLEN);    
  24.     
  25. /*直接调用该函数,将数据包从网卡上发送出去*/    
  26.     
  27. ret = dev_queue_xmit(skb);    
  这里还要顺便说一下构造的数据包发送完毕之后,对于hook函数的返回值问题。 

   (1)第一种发送数据包的实现,对于send_reset函数的实现中,由于单独申请了nskb的内存,并构造的新的数据包。新数据包接着走NF的流程了。而对于原始的skb,就通过模块的返回值return NF_DROP做出了处理。 
   (2)第二种发送数据包的实现,若是基于已有数据包的基础上重新构造的数据包,那么实际上原始数据包的内容已经不复存在,而且调用完毕 dev_queue_xmit已将同一块缓冲区,只是填充了新数据的数据包发送出去,因此,这里已经没有原始数据包的存在了,需要返回 NF_STOLEN,告诉协议栈不用关心原始的包即可。否则,若是新数据包是单独申请的内存,那么对于原数据包还应该是返回NF_DROP.

这篇关于Linux内核构造数据包并发送(二)(dev_queue_xmit方式)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/682096

相关文章

java实现docker镜像上传到harbor仓库的方式

《java实现docker镜像上传到harbor仓库的方式》:本文主要介绍java实现docker镜像上传到harbor仓库的方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 前 言2. 编写工具类2.1 引入依赖包2.2 使用当前服务器的docker环境推送镜像2.2

Linux中SSH服务配置的全面指南

《Linux中SSH服务配置的全面指南》作为网络安全工程师,SSH(SecureShell)服务的安全配置是我们日常工作中不可忽视的重要环节,本文将从基础配置到高级安全加固,全面解析SSH服务的各项参... 目录概述基础配置详解端口与监听设置主机密钥配置认证机制强化禁用密码认证禁止root直接登录实现双因素

java向微信服务号发送消息的完整步骤实例

《java向微信服务号发送消息的完整步骤实例》:本文主要介绍java向微信服务号发送消息的相关资料,包括申请测试号获取appID/appsecret、关注公众号获取openID、配置消息模板及代码... 目录步骤1. 申请测试系统2. 公众号账号信息3. 关注测试号二维码4. 消息模板接口5. Java测试

在Linux终端中统计非二进制文件行数的实现方法

《在Linux终端中统计非二进制文件行数的实现方法》在Linux系统中,有时需要统计非二进制文件(如CSV、TXT文件)的行数,而不希望手动打开文件进行查看,例如,在处理大型日志文件、数据文件时,了解... 目录在linux终端中统计非二进制文件的行数技术背景实现步骤1. 使用wc命令2. 使用grep命令

springboot项目打jar制作成镜像并指定配置文件位置方式

《springboot项目打jar制作成镜像并指定配置文件位置方式》:本文主要介绍springboot项目打jar制作成镜像并指定配置文件位置方式,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录一、上传jar到服务器二、编写dockerfile三、新建对应配置文件所存放的数据卷目录四、将配置文

Linux如何快速检查服务器的硬件配置和性能指标

《Linux如何快速检查服务器的硬件配置和性能指标》在运维和开发工作中,我们经常需要快速检查Linux服务器的硬件配置和性能指标,本文将以CentOS为例,介绍如何通过命令行快速获取这些关键信息,... 目录引言一、查询CPU核心数编程(几C?)1. 使用 nproc(最简单)2. 使用 lscpu(详细信

linux重启命令有哪些? 7个实用的Linux系统重启命令汇总

《linux重启命令有哪些?7个实用的Linux系统重启命令汇总》Linux系统提供了多种重启命令,常用的包括shutdown-r、reboot、init6等,不同命令适用于不同场景,本文将详细... 在管理和维护 linux 服务器时,完成系统更新、故障排查或日常维护后,重启系统往往是必不可少的步骤。本文

基于Linux的ffmpeg python的关键帧抽取

《基于Linux的ffmpegpython的关键帧抽取》本文主要介绍了基于Linux的ffmpegpython的关键帧抽取,实现以按帧或时间间隔抽取关键帧,文中通过示例代码介绍的非常详细,对大家的学... 目录1.FFmpeg的环境配置1) 创建一个虚拟环境envjavascript2) ffmpeg-py

gitlab安装及邮箱配置和常用使用方式

《gitlab安装及邮箱配置和常用使用方式》:本文主要介绍gitlab安装及邮箱配置和常用使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1.安装GitLab2.配置GitLab邮件服务3.GitLab的账号注册邮箱验证及其分组4.gitlab分支和标签的

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri