ARP攻击,是针对以太网地址解析协议(ARP)的一种攻击技术。在局域网中,ARP病毒收到广播的ARP 请求包,能够解析出其它节点的 (IP, MAC) 地址, 然后病毒伪装为目的主机,告诉源主机一个假MAC地址,这样就使得源主机发送给目的主机的所有数据包都被病毒软件截取,而源主机和目的主机却浑然不知。ARP攻击通过伪造IP地址和MAC地址实现ARP欺骗,能够在网络中产生大量的ARP通信量使网络阻塞,攻击者只要持续不断的发出伪造的ARP响应包就能更改目标主机ARP缓存中的IP-MAC条目。ARP协议在设计时未考虑网络安全方面的特性,这就注定了其很容易遭受ARP攻击。黑客只要在局域网内阅读送上门来的广播ARP请求数据包,就能偷听到网内所有的 (IP, MAC)地址。而源节点收到ARP 响应时,它也不会质疑,这样黑客很容易冒充他人。

  这一节主要针对ARP讲解ARP表的创建,更新,查询等操作。这里我们先从几个简单的函数入手讲解ARP各个子模块功能,然后再将各个模块与上层协议结合起来,宏观的讲解ARP模块。

  第一个需要迫不及待要说的函数是find_entry该函数最重要的输入是一个IP地址返回值是该IP地址对应的ARP缓存表项索引。函数声明原型如下,

static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags)

  这里,很有必要翻译一下源代码中注释的内容:该函数主要功能是寻找一个匹配的ARP表项或者创建一个新的ARP表项,并返回该表项的索引号如果参数ipaddr为给定的非空的内容,则函数需要返回一个处于pendingstable的索引表项如果没有匹配的表项,则该函数需要返回一个empty的表项但该表项的IP字段的值要被设置为ipaddr的值,这种情况下,find_entry函数返回后,调用者需要将表项从状态empty改为pending。还有一种情况,如果参数ipaddr为空值,同样返回一个状态为empty的表项

  返回状态为empty的表项首先从状态标示为empty的空闲ARP表项中选取,如果这样的表项都用完了,同时参数flags的值被设置为ETHARP_TRY_HARD,则find_entry回收最老的ARP表项,将该表项设置为empty状态返回

  这个函数比较大,有将近200行代码,这里就不贴了,直接讲讲它的工作流程。

  首先,lwip有一个比较巧妙的地方,它并不是冲上去就是就把ARP缓存中所有的表项搜索一遍,而是做了一个假设,假设这次的表项索引还是上一次的(在很多情况下就是这样的)。所以,LWIP中有个全局的变量etharp_cached_entry,它始终保存着上次用到的索引号,如果这个索引恰好就是我们要找的内容,且索引的表项已经处于stable状态,那就直接返回这个索引号就完成了

  如果情况不够理想,就必须去检索整个ARP表了,检索的过程是从ARP表的第一个表项开始,依次往后检索直至最后一个表项,过程较复杂。对于每个表项首先判断它是否为empty状态find_entry只关心第一个状态为empty的表项索引值,对该索引值以后的empty表项不感兴趣,忽略。如果一个表项不是empty状态,则判断它是不是pending状态对于pending状态的表项,需要做以下的事情,先看看它里面存的**IP地址和我们的ipaddr是否匹配**,如果匹配,好返回该索引值,记住还要更新etharp_cached_entry为该索引值,如果不匹配,则判断该索引的数据包指针是否为空,find_entry试图记录生存时间最长的pending状态有数据缓冲或无数据缓冲的表项索引如果一个表项也不是pending状态,则判断它是不是stable状态。对于stable状态的表项,与pending状态的表项处理过程相似, find_entry试图记录生存时间最长的stable表项的索引

  如果到这里都还没有找到匹配的表项,那就很杯具了,我们需要为find_entry调用者返回一个empty的表项索引。经过上面一段后,find_entry已经知道了第一个empty状态表项的索引生存时间最老的pending状态且有数据缓冲表项的索引生存时间最老的pending状态且无数据缓冲表项的索引生存时间最老的stable状态表项的索引,我们暂且先将这四个值假设为a、b、c、d。如果参数flags的值被设置为ETHARP_TRY_HARD,那么find_entry按照a-->d-->c-->b的顺序选择一个合适的索引返回。find_entry首先判断a是否在ARP表项范围内,如果是,则选择a,如果不是,则判断b是否在ARP表项范围内,依此类推。当选中一个索引后,随即就会将该索引对应的表项设置为empty态,并且将该表项的IP地址设置为ipaddr的值,ctime值设置为0,最后返回索引。至此,find_entry大功告成!

  接下来的一个函数是etharp_query,该函数的功能是向给定的IP地址发送一个数据包或者发送一个ARP请求,当然情况远不如此简单。还是很有必要翻译一下源代码中函数功能注释的内容如果给定的IP地址不在ARP表中,则一个新的ARP表项会被创建,此时该表项处于pending状态,同时一个关于该IP地址的ARP请求包会被广播出去,再同时要发送的数据包会被挂接在该表项的数据缓冲指针上如果IP地址在ARP表中有相应的表项存在,但该表项处于pending状态,则操作与前者相同,发送一个ARP请求和挂接数据包;如果IP地址在ARP表中有相应的表项存在,表项处于stable状态,此时来判断给定的数据包是否为空,不为空则直接将该数据包发送出去,为空则向该IP地址发送一个ARP请求。

  etharp_query函数原型如下所示,源代码在150行左右,这里主要讲解其流程:

err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)

  (1) 首先判断给定的ipaddr是否合法,对于空IP地址、广播IP地址、多播IP地址不予处理。

  (2) 将ipaddr作为参数调用函数find_entry,函数返回一个ARP表项索引,该表项可能是原来已经有的,此时该表项应该是pendingstable状态;该表项也可能是新申请得到的,此时该表项应该是empty状态。

  (3) 根据返回的表项索引找到该ARP表项,判断该表项是否为empty状态,如果是,说明该表项是新申请的,则将该表项状态设置为pending状态。

  (4) 判断要发送的数据包是否为空,或者判断ARP表项是否为pending状态,这两个条件只要有一个成立,就发送一个ARP请求出去,发送ARP请求的函数是etharp_request

  (5) 如果待发送的数据包不为空,此刻就根据ARP表项的状态作不同的处理ARP表项处于**stable状态**,则直接调用函数etharp_send_ip发送数据包ARP表项处于**pending状态**,需要将该数据包挂接到表项的待发送数据链表上,由于pending状态的表项必然在第(4)步中发出了一个ARP请求,当内核接收到ARP回应时,会将表项设置为stable状态,并将其链表上的数据全部发送出去,当然这项工作具体是怎样完成的那是后话了。

  将数据包挂接在表项的发送链表上,这又是一个较复杂的过程:最重要的一点是判断该数据包pbuf的类型对于PBUF_REFPBUF_POOLPBUF_RAM的数据包不能直接挂在发送链表上,因为这些数据包在被挂接后并不会被立刻发送出去,这可能导致数据包在等待发送的过程中内部数据被改动。对于以上这些类型的待发送数据包,需要将数据拷贝至新的pbuf中,然后将新的pbuf挂接至发送链表。至此,etharp_query函数功德圆满!

lwip---(七)ARP表查询相关推荐

  1. SylixOS网络协议栈---Lwip协议栈之ARP表

    1 适用范围 本文档适用于分析SylixOS网络相关问题的技术人员. 2 ARP介绍 地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个 ...

  2. MySQL --- 多表查询 - 七种JOINS实现、集合运算、多表查询练习

    七种JOINS实现 左上图的JOIN是左外连接,右上图的JOIN是右外连接,中间图的JOIN是内连接,左中图的JOIN在左上图的基础上再去掉中间重复的,只需要 A 在 B 中没有的部分(空的部分),右 ...

  3. 七、MySQL 多表查询详解(附练习题及答案----超详细)

    文章目录 一.笛卡尔积(或交叉连接)的理解 二.多表查询分类讲解 2.1 分类1:等值连接 vs 非等值连接 2.2 分类2:自连接 vs 非自连接 2.3 分类3:内连接 vs 外连接 2.4 SQ ...

  4. mysql创表的工种_[MySQL基础]七、连接查询

    含义:又称为多表查询,当查询的字段来自多个表时,就会用到连接查询 笛卡尔乘积现象 表1 有m行,表2有n行,结果为m*n行 发生原因:没有有效的连接条件. 如何避免:添加有效的连接条件. 案例:在bo ...

  5. Mysql数据库基本操作(七)多表查询-子查询,表自身关联查询

    多表查询还有前面的两块内容--内连接查询,外连接查询,希望看到这篇博客的朋友先去看看我的"Mysql数据库"专栏中Mysql数据库基本操作(六)多表查询-内连接,外连接这一章博客, ...

  6. 第七章、模型详解 -- 多表查询

    通过对象进行多表查询 由一到多查询:一类模型类对象名.小写多类模型类类名_set.查询函数() 通过对象查询分成2步,先查到某本图书,再通过该图书对象查询该图书中的人物对象 实例演练: 查询id为1的 ...

  7. 第七周 Java语法总结之数据库大全_DDL_DML_DQL_约束_备份与还原_表的关系_三大范式_多表查询(内连接_外连接_子查询)_musql事务_隔离级别

    文章目录 数据库 DDL语句:数据库定义语句 1.库的增删查改 1.查询当前mysql下所有的数据库 2.创建数据库 3.查看创建数据库的默认的字符集(了解) 4.修改数据库的字符集(了解) 5.删除 ...

  8. lwip之ARP协议概念

    什么是ARP协议 ARP(Address Resolution Protocol)协议是地址转换协议.负责将IP地址转换为MAC地址.在OSI参考模型中属于网络层,和IP协议同属于同一层,但是在逻辑上 ...

  9. Android数据库专家秘籍(七)经验LitePal查询艺术

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/40153833 经过了多篇文章的学习,我们已经把LitePal中的绝大部分内容都掌握 ...

  10. MySQL之单表查询

    一.关键字的执行优先级 1,from:找到表 2,where:拿着where指定的约束条件,去文件/表中取出一条条数据 3,group by:将取出的一条条数据进行分组,如果没有group by,则整 ...

最新文章

  1. AI一分钟 | 英伟达发布最强核弹—无人车AI芯片DRIVE Xavier;百度硅谷首次开放无人车试乘:上车前要先签免责书
  2. 插入顶部_轻巧的衣领插入技术
  3. Linux Device和Driver注册过程,以及Probe的时机
  4. 列表ListView和列表选择框的使用编写步骤
  5. 报任安书文言现象_干货丨文言文句式详解,快点收藏!
  6. office漏洞利用--获取shell
  7. oracle带时间查询语句,请教oracle按时间分组查询语句的写法
  8. multisim连接MySQL_首次使用Multisim软件进行电路仿真设计
  9. java基础试题_Java基础测试题带答案
  10. 常量、变量;基本数据类型;input()、if、while、break、continue
  11. python老男孩14期_老男孩Python完美实战课程 14期视频教程 28周Python视频教程 1-14周部分...
  12. python包 —rdkit 安装
  13. iOS TextField收取键盘的方法
  14. Golang sync.Cond详细理解
  15. IDM产品安全机制说明
  16. 桂林理工大学南宁分校php实训,桂林理工大学南宁分校冶金化工虚拟仿真实验教学中心...
  17. Lyft开源L5无人车数据集:55000个3D注释框架,还有空间语义地图
  18. 量子计算机量子纠缠,最新“量子纠缠”原子使量子计算机更进一步
  19. Deauth Flood 攻击
  20. Solaris 11中配置基于link的IPMP

热门文章

  1. 运维人员须熟悉的38个运维工具汇总
  2. 用n=4的复化Simpson公式求积分方程的近似解[matlab]
  3. 虚幻airsim1:下载安装
  4. linux opendir路径_Linux C - opendir 和 readdir 和 closedir - 目录文件打开
  5. echarts文档解读
  6. my android机器人作文,机器人作文400字
  7. 删除magisk模块
  8. excel相同字段多行合并_EXCEL里如何快速把多行数据合并为一行并以逗号隔开?...
  9. 流加密,一次性密码本的原理,简介,事例以及攻击方式
  10. Python3制作网易云音乐下载器!付费的你猜能下载吗!