博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux内核构造数据包并发送(二)(dev_queue_xmit方式)
阅读量:4139 次
发布时间:2019-05-25

本文共 2219 字,大约阅读时间需要 7 分钟。

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]
  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.

转载地址:http://vmhvi.baihongyu.com/

你可能感兴趣的文章
主动调用abort函数使程序coredump
查看>>
在这种情况下居然strings不出结果, 呵呵哒!
查看>>
linux shell中“=”左右不能有空格, 晕不晕
查看>>
“王者荣耀”中的常用英语
查看>>
重温乔布斯在斯坦福大学的经典演讲------Stay Hungry, Stay Foolish
查看>>
一个易错的面试题来加深对C++多态的理解
查看>>
满大街都是这种烂题目------从100亿个整数中找出最大的1000个整数
查看>>
一个台阶有n阶,一人每次可跳1,2……,最多一次跳n阶,问这个人跳上去有多少种跳法?
查看>>
又是考查内存对齐和指针理解, 简单东西。
查看>>
将文件中所有的abc替换为def
查看>>
再玩下linux中的的epoll函数------可以用任何描述符号fd而不限于网络socket
查看>>
csdn博客栏目装修大全------如何植入“微信打赏”、“微信公众号”等
查看>>
红黑树(RB-tree)比AVL树的优势在哪?
查看>>
为什么是红黑树而不是绿黄树?
查看>>
微信网页版扫码登录是如何实现的?
查看>>
第三方账号登陆还是自主账号登录?
查看>>
《自由人》陈苓峰------互联网实现了自由人的自由联合, 这是一个天翻地覆的时代!
查看>>
对QQ、微信等第三方登录的几个思考
查看>>
拖库 洗库 撞库
查看>>
md5破解和彩虹表
查看>>